Re: [PATCH v2 2/4] of: reimplement the matching method for __of_match_node()
On Wed, Feb 19, 2014 at 02:21:02PM +0800, Kevin Hao wrote: > + /* > + * Matching compatible is better than matching type and name, > + * and the specific compatible is better than the general. > + */ > + if (matches->compatible[0] && > + __of_device_is_compatible_score(node, > + matches->compatible, &score)) > + score = INT_MAX - 4 * score; It seems that we also need to adjust the above as what we do for the type and name. The v3 is coming. Thanks, Kevin pgpzNcFByYije.pgp Description: PGP signature
Re: [PATCH 01/15] regulator: wm8350: Do not hardcode return value
On Tue, Feb 18, 2014 at 04:10:57PM +0530, Sachin Kamat wrote: > Propagate the error value returned by the function instead. Applied, thanks. signature.asc Description: Digital signature
Re: [PATCH v2 1/5] mfd: add bcm590xx pmu DT binding
On Tue, Feb 18, 2014 at 06:17:08PM -0500, Matt Porter wrote: > + > + rfldo_reg: regulator@0 { > + reg = <0>; What do these reg values mean, they don't seem to be documented in the binding? signature.asc Description: Digital signature
Re: [PATCH v2 5/5] ARM: dts: add bcm590xx pmu support and enable for bcm28155-ap
On Tue, Feb 18, 2014 at 06:17:12PM -0500, Matt Porter wrote: > + csr_reg: regulator@13 { > + reg = <13>; > + regulator-compatible = "csr"; > + regulator-min-microvolt = <86>; > + regulator-max-microvolt = <144>; > + }; You should not be setting voltage ranges like this in a .dtsi - you've no idea if these voltage ranges are in fact valid for any given board so they can't be set safely. In general I would not expect to see any configuration at all for regulators in an include file for the chip. signature.asc Description: Digital signature
Re: [PATCH v2 2/5] mfd: add bcm590xx pmu driver
On Tue, Feb 18, 2014 at 06:17:09PM -0500, Matt Porter wrote: > +config MFD_BCM590XX > + bool "Broadcom BCM590xx PMUs" > + select MFD_CORE > + select REGMAP_I2C > + depends on I2C=y > + help > + Support for the BCM590xx PMUs from Broadcom > + Why does this need to be built in? signature.asc Description: Digital signature
Re: [PATCH] Fix flags for initramfs LZ4 compression
Hello, On Tue, Feb 18, 2014 at 04:08:56PM -0800, Andrew Morton wrote: > On Sat, 15 Feb 2014 18:14:57 -0500 "Daniel M. Weeks" > wrote: > > > LZ4 as implemented in the kernel differs from the default method now > > used by the reference implementation of LZ4. Until the in-kernel method > > is updated to support the new default, passing the legacy flag (-l) to > > the compressor is necessary. Without this flag the kernel-generated, > > LZ4-compressed initramfs is junk. > > > > ... > > > > --- a/scripts/gen_initramfs_list.sh > > +++ b/scripts/gen_initramfs_list.sh > > @@ -257,7 +257,7 @@ case "$arg" in > > && compr="lzop -9 -f" > > echo "$output_file" | grep -q "\.lz4$" \ > > && [ -x "`which lz4 2> /dev/null`" ] \ > > -&& compr="lz4 -9 -f" > > +&& compr="lz4 -l -9 -f" > > echo "$output_file" | grep -q "\.cpio$" && compr="cat" > > shift > > ;; > > What happens is the user is running an old version of /bin/lz4? A > version which predates this switch to a new format? Do those earlier > versions accept -l, even though they don't need it? Or will the kernel > build fail? It seems that lz4 supports legacy format with the same option as lz4c does. Just looking at the first few bytes of lz4 compressed image, we can see whether it is new format or not. It shows new format magic number without this patch. New format magic number is 0x184d2204. $ hexdump -C ./initramfs_data.cpio.lz4 |more 04 22 4d 18 64 70 b9 69 (Little Endian) ... Currently Kernel supports legacy format only. Acked-by: Kyungsik Lee Thanks, Kyungsik -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 3/5] regulator: add bcm590xx regulator driver
On Tue, Feb 18, 2014 at 06:17:10PM -0500, Matt Porter wrote: > +static struct of_device_id bcm590xx_of_match[] = { > + { .compatible = "brcm,bcm59056-regs", }, > + { } > +}; This looks pretty much OK however I am in general suspicious of MFDs that have subdevices like this in the DT - it doesn't seem like this is a reusable device which can appear anywhere else so you're pretty much just representing the way that Linux splits things up here rather than a reusable IP that can reasonably have a separate binding. If you had a binding which did something like enumerate the individual IP blocks as individual devices that'd be more interesting, I could see for example that a different PMIC might have a different set of register compatible regulator IPs laid out. It looks like that might be doable, but it's in no way essential. signature.asc Description: Digital signature
Re: [PATCH 1/2] driver: regmap: add regmap_parse_val api
On Wed, Feb 19, 2014 at 01:28:43PM +0800, Nenghua Cao wrote: >Update Liam and Mark's mail. I can't do anything useful with patches that are quoted, sorry. None of the tools know how to strip out quotes. signature.asc Description: Digital signature
Re: [PATCH 1/2] regulator: tps65218: Add terminate entry for of_device_id table
On Tue, Feb 18, 2014 at 08:20:59PM +0800, Axel Lin wrote: > Fixes below build error: > FATAL: drivers/regulator/tps65218-regulator: struct of_device_id is not > terminated with a NULL entry! This is good (though I'm not seeing a build time error myself...). > Also remove of_match_ptr as this is a DT-only driver. This should really have been split out as a separate change. We probably also need an OF dependency in the Kconfig for this (there may be one on the MFD but having one here if the driver specficaly depends on DT is better to avoid bisection issues if the MFD gets updated). signature.asc Description: Digital signature
Re: mm: OS boot failed when set command-line kmemcheck=1
On Wed, 19 Feb 2014, Xishi Qiu wrote: > Hi all, > > CONFIG_KMEMCHECK=y and set command-line "kmemcheck=1", I find OS > boot failed. The kernel is v3.14.0-rc3 > > If set "kmemcheck=1 nowatchdog", OS will boot successfully. > I have automated kernel boots that have both "kmemcheck=0" and "kmemcheck=1" as the last parameter in the kernel command line every night and I've never seen it fail on tip or linux-next before. So I'm sure I won't be able to reproduce your issue, but it may have something to do with your bootloader that isn't described above. The sscanf() really wants to be replaced with kstrtoint(). Could you try this out? diff --git a/arch/x86/mm/kmemcheck/kmemcheck.c b/arch/x86/mm/kmemcheck/kmemcheck.c --- a/arch/x86/mm/kmemcheck/kmemcheck.c +++ b/arch/x86/mm/kmemcheck/kmemcheck.c @@ -78,10 +78,16 @@ early_initcall(kmemcheck_init); */ static int __init param_kmemcheck(char *str) { + int val; + int ret; + if (!str) return -EINVAL; - sscanf(str, "%d", &kmemcheck_enabled); + ret = kstrtoint(str, 0, &val); + if (ret) + return ret; + kmemcheck_enabled = val; return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH net-next 12/14] r8152: replace netif_rx withnetif_receive_skb
hayeswang : > Francois Romieu [mailto:rom...@fr.zoreil.com] > > Hayes Wang : > > > Replace netif_rx with netif_receive_skb to avoid disabling irq frequently > > > for increasing the efficiency. > > > > read_bulk_callback is issued in irq context. It could thus use plain > > spin_lock / spin_unlock instead of the irq disabling version. > > The rx_bottom() is called in tasklet, so I just think I could use > netif_receive_skb directly. The netif_rx seems to queue the packet, > and local_irq_disable() would be called before dequeuing the skb. The change in rx_bottom is fine. My point is about read_bulk_callback. rx_bottom races with read_bulk_callback. rx_bottom is issued in tasklet (softirq) context. read_bulk_callback is issued in irq context, with irq disabled. read_bulk_callback does not need to disable irq itself and could go with spin_lock in place of spin_lock_irqsave (rx_bottom can't, of course). -- Ueimor -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/4] Staging: comedi: addi-data: don't initialize a static variable to 0
In hwdrv_apci1564.c, one static variable is zero initialized. This is unneeded and redundant, so we remove the initialization. Signed-off-by: Chase Southwood --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 21dd028..2b47fa1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -100,7 +100,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY #define APCI1564_TCW_WARN_TIMEBASE 28 /* Global variables */ -static unsigned int ui_InterruptStatus_1564 = 0; +static unsigned int ui_InterruptStatus_1564; static unsigned int ui_InterruptData, ui_Type; /* -- 1.8.5.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/4] Staging: comedi: addi-data: replace printk() with dev_err() in hwdrv_apci1564.c
There were a small handful of printk() calls in hwdrv_apci1564.c. It is generally better to use dev_err() for error messages instead, so I switched all the printk() calls out, as well as cleaned up the error strings. Signed-off-by: Chase Southwood --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 66e6e68..21dd028 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -414,7 +414,7 @@ static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, devpriv->iobase + ((data[5] - 1) * 0x20) + APCI1564_TCW_PROG); } else { - printk(" Invalid subdevice."); + dev_err(dev->class_dev, "Invalid subdevice.\n"); } return insn->n; @@ -472,7 +472,7 @@ static int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *d APCI1564_TCW_PROG); break; default: - printk("\nSpecified functionality does not exist\n"); + dev_err(dev->class_dev, "Specified functionality does not exist.\n"); return -EINVAL; } } @@ -591,7 +591,7 @@ static int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, } else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG) && (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) { - printk("\n Invalid Subdevice !!!\n"); + dev_err(dev->class_dev, "Invalid Subdevice!\n"); } return insn->n; } @@ -665,7 +665,7 @@ static void v_APCI1564_Interrupt(int irq, void *d) APCI1564_TCW_IRQ) & 0x1; if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0 && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) { - printk("\nInterrupt from unknown source\n"); + dev_err(dev->class_dev, "Interrupt from unknown source.\n"); } if (ui_DI == 1) { -- 1.8.5.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/4] Staging: comedi: addi-data: cleanup comments in hwdrv_apci1564.c
hwdrv_apci1564.c had a lot of commented out conditional statements that were often identical to other un-commented out statements nearby, so it should be safe to just delete all of these commented out lines. This patch also converts the remaining comments to the preferred kernel style for comments. Signed-off-by: Chase Southwood --- Moving onto a new addi-data driver. Generally mostly the same issues though. .../comedi/drivers/addi-data/hwdrv_apci1564.c | 93 +- 1 file changed, 38 insertions(+), 55 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 8466854..ff556cc 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -138,9 +138,8 @@ static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct addi_private *devpriv = dev->private; devpriv->tsk_Current = current; - /***/ + /* Set the digital input logic */ - /***/ if (data[0] == ADDIDATA_ENABLE) { data[2] = data[2] << 4; data[3] = data[3] << 4; @@ -154,13 +153,13 @@ static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, outl(0x4, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ); - } /* if (data[1] == ADDIDATA_OR) */ + } else { outl(0x6, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ); - } /* else if (data[1] == ADDIDATA_OR) */ - } /* if (data[0] == ADDIDATA_ENABLE) */ + } + } else { outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + @@ -171,7 +170,7 @@ static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ); - } /* else if (data[0] == ADDIDATA_ENABLE) */ + } return insn->n; } @@ -225,25 +224,25 @@ static int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, comedi_error(dev, "Not a valid Data !!! ,Data should be 1 or 0\n"); return -EINVAL; - } /* if ((data[0]!=0) && (data[0]!=1)) */ + } if (data[0]) { devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; - } /* if (data[0]) */ + } else { devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; - } /* else if (data[0]) */ + } if (data[1] == ADDIDATA_ENABLE) { ul_Command = ul_Command | 0x1; - } /* if (data[1] == ADDIDATA_ENABLE) */ + } else { ul_Command = ul_Command & 0xFFFE; - } /* else if (data[1] == ADDIDATA_ENABLE) */ + } if (data[2] == ADDIDATA_ENABLE) { ul_Command = ul_Command | 0x2; - } /* if (data[2] == ADDIDATA_ENABLE) */ + } else { ul_Command = ul_Command & 0xFFFD; - } /* else if (data[2] == ADDIDATA_ENABLE) */ + } outl(ul_Command, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_INTERRUPT); @@ -323,7 +322,7 @@ static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, outl(data[3], devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_RELOAD_VALUE); - } /* if (data[0]==ADDIDATA_WATCHDOG) */ + } else if (data[0] == ADDIDATA_TIMER) { /* First Stop The Timer */ ul_Command1 = @@ -357,13 +356,12 @@ static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, outl(0x0, devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_IRQ); - } /* if (data[1]==1) */ + } else { outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* disable Timer interrupt */ - } /* else if (data[1]==1) */ + } /* Loading Timebase */ - outl(data[2], devpriv->i_IobaseAmcc + APCI1564_TIMER
[PATCH 2/4] Staging: comedi: addi-data: cleanup brace usage in hwdrv_apci1564.c
hwdrv_apci1564.c had many single statments wrapped in braces, so we can delete these. Also, some else statements were improperly placed, fix these too. Signed-off-by: Chase Southwood --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 58 -- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index ff556cc..66e6e68 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -153,14 +153,12 @@ static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, outl(0x4, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ); - } - else { + } else { outl(0x6, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ); } - } - else { + } else { outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_INTERRUPT_MODE1); @@ -225,24 +223,22 @@ static int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, "Not a valid Data !!! ,Data should be 1 or 0\n"); return -EINVAL; } - if (data[0]) { + + if (data[0]) devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; - } - else { + else devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; - } - if (data[1] == ADDIDATA_ENABLE) { + + if (data[1] == ADDIDATA_ENABLE) ul_Command = ul_Command | 0x1; - } - else { + else ul_Command = ul_Command & 0xFFFE; - } - if (data[2] == ADDIDATA_ENABLE) { + + if (data[2] == ADDIDATA_ENABLE) ul_Command = ul_Command | 0x2; - } - else { + else ul_Command = ul_Command & 0xFFFD; - } + outl(ul_Command, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_INTERRUPT); @@ -322,8 +318,7 @@ static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, outl(data[3], devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_RELOAD_VALUE); - } - else if (data[0] == ADDIDATA_TIMER) { + } else if (data[0] == ADDIDATA_TIMER) { /* First Stop The Timer */ ul_Command1 = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER + @@ -356,8 +351,7 @@ static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, outl(0x0, devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_IRQ); - } - else { + } else { outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* disable Timer interrupt */ } @@ -377,8 +371,7 @@ static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, ul_Command1 = (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL; outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* mode 2 */ - } - else if (data[0] == ADDIDATA_COUNTER) { + } else if (data[0] == ADDIDATA_COUNTER) { devpriv->b_TimerSelectMode = ADDIDATA_COUNTER; devpriv->b_ModeSelectRegister = data[5]; @@ -420,8 +413,7 @@ static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, outl(ul_Command1, devpriv->iobase + ((data[5] - 1) * 0x20) + APCI1564_TCW_PROG); - } - else { + } else { printk(" Invalid subdevice."); } @@ -495,8 +487,7 @@ static int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *d outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); - } - else if (data[1] == 0) { + } else if (data[1] == 0) { /* Stop The Timer */ ul_Command1 = @@ -515,13 +506,11 @@ static int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *d if (data[1] == 1) { /* Start the Counter subdevice */ ul_Command1 = (ul_Command1 & 0xF9FFUL) | 0x1UL; - } - else if (data[1]
Re: [PATCH] drm/i915/opregion: work around buggy firmware that provides 8+ output devices
On Wed, Feb 19, 2014 at 03:31:29PM +0800, Aaron Lu wrote: > DID2 is in system memory region and has some assigned value like 0x400 > when we read it. For this case it is easy since there is only one output > device that is of type LVDS so we can match it to connector of type eDP > or LVDS, suppose there is only one such connector. But for output > devices' whose _ADR has the value of 0x301, 0x302, etc. I have no idea > how to match them up to the connectors of that type as we can't be sure > the probe order we have used in i915 driver is the same as BIOS'. Non-standard _ADR values are assigend by the GPU vendor, so Intel should be able to provide you with the correct interpretations. -- Matthew Garrett | mj...@srcf.ucam.org -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] drm/i915/opregion: work around buggy firmware that provides 8+ output devices
On 02/13/2014 08:03 PM, Daniel Vetter wrote: > On Thu, Feb 13, 2014 at 11:08 AM, Chris Wilson > wrote: >> On Thu, Feb 13, 2014 at 05:10:25PM +0800, Aaron Lu wrote: >>> On 02/12/2014 06:31 PM, Chris Wilson wrote: On Wed, Feb 12, 2014 at 11:05:40AM +0800, Aaron Lu wrote: > The ACPI table on ASUS UX302LA has more than 8 output devices under the > graphics controller device node. The problem is, the real active output > device, the LCD panel, is listed the last. The result is, the LCD's > device id doesn't get recorded in the active device list CADL array and > when the _DCS control method for the LCD device is executed, it returns > 0x1d, meaning it is not active. This affects the hotkey delivery ASL > code that will not deliver a notification if the output device is not > active on backlight hotkey press. > > I don't see a clean way to solve this problem since the operation region > spec doesn't allow more than 8 output devices so we have no way of > storing all these output devices. The fact that output devices that have > _BCM control method usually means they have a higher possibility of being > used than those who don't made me choose a simple way to work around > the buggy firmware by replacing the last entry in CADL array with the one > that has _BCM control method. There is no specific reason why the last > entry is picked instead of others. Another possibility is that the connector list is in rough priority order so might be useful for sorting the CADL array. Since the CADL should only be a list of currently active devices, we could just bite the bullet and repopulate it correctly after every setcrtc. >>> >>> Thanks for the suggestion. As a first step, does the following un-tested >>> patch look OK? >> >> Yes. Maybe worth putting together the similar routines for blind >> setting the didl and the cadl, or at least for computing the value from >> the connector. For instance, the didl logic disagrees with the value of >> index - is that relevant? I have a suspicion that the CADL entry should >> match the DIDL entry for the connector, but that is not actually >> mentioned in the opregion spec afaict. > > I think a problem is that often we have more than one output for a > given type. So we need to somehow match them up to make sure we put > the right ones intot didl/cadl lists. The issue here is that our > connectors don't match up perfectly with the acpi output entries > (since we have separate dp/hdmi outputs). But I think it would be > worthwhile trying to match them up and store a link from struct > intel_connector to the right acpi node acpi node. Is this possible? I don't see a way to match them up... The _ADR control method uses a field that seems to be assigned by BIOS like this: Device (LCDD) { Method (_ADR, 0, Serialized) // _ADR: Address { Return (And (0x, DID2)) } } DID2 is in system memory region and has some assigned value like 0x400 when we read it. For this case it is easy since there is only one output device that is of type LVDS so we can match it to connector of type eDP or LVDS, suppose there is only one such connector. But for output devices' whose _ADR has the value of 0x301, 0x302, etc. I have no idea how to match them up to the connectors of that type as we can't be sure the probe order we have used in i915 driver is the same as BIOS'. In the mean time, it seems we can just use driver's information to populate both DIDL and CADL and forget the _ADR of those devices like the following patch does: diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a4ffc021c317..55956a517a77 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -204,6 +204,9 @@ struct intel_connector { /* since POLL and HPD connectors may use the same HPD line keep the native state of connector->polled in case hotplug storm detection changes it */ u8 polled; + + /* device id with type and index information */ + u32 disp_id; }; typedef struct dpll { diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 68459605bd12..ba08c894ce9a 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -221,11 +221,11 @@ struct opregion_asle { #define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19) #define SWSCI_SBCB_ENABLE_DISABLE_AUDIOSWSCI_FUNCTION_CODE(SWSCI_SBCB, 21) -#define ACPI_OTHER_OUTPUT (0<<8) -#define ACPI_VGA_OUTPUT (1<<8) -#define ACPI_TV_OUTPUT (2<<8) -#define ACPI_DIGITAL_OUTPUT (3<<8) -#define ACPI_LVDS_OUTPUT (4<<8) +#define ACPI_OTHER_OUTPUT 0 +#define ACPI_VGA_OUTPUT 1 +#define ACPI_TV_OUTPUT 2 +#define ACPI_DIGITAL_OUTPUT 3 +#define ACPI_LV
RE: [PATCH 2/4] ARM: dts: Enable SAI ALSA SoC DAI device for Vybrid VF610 TOWER board.
> The patch subject can be a little short like > > ARM: dts: vf610-twr: Enable SAI ALSA SoC DAI device > Yes, that looks better. Thanks, -- Best Regards, Xiubo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH 2/4] ARM: dts: Enable SAI ALSA SoC DAI device for Vybrid VF610 TOWER board.
> > @@ -127,9 +127,27 @@ > > VF610_PAD_PTB5__UART1_RX0x21a1 > > >; > > }; > > + > > + pinctrl_sai2: sai2grp { > > To sort it alphabetically, the entry should be added before > pinctrl_uart1. > > > + fsl,pins = < > > + VF610_PAD_PTA16__SAI2_TX_BCLK 0x02ed > > + VF610_PAD_PTA18__SAI2_TX_DATA 0x02ee > > + VF610_PAD_PTA19__SAI2_TX_SYNC 0x02ed > > + VF610_PAD_PTA21__SAI2_RX_BCLK 0x02ed > > + VF610_PAD_PTA22__SAI2_RX_DATA 0x02ed > > + VF610_PAD_PTA23__SAI2_RX_SYNC 0x02ed > > + VF610_PAD_PTB18__EXT_AUDIO_MCLK 0x02ed > > Use tabs instead of spaces. > > Shawn > Yes, I'll fix these two issues above. Thanks, -- Best Regards, Xiubo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH 1/4] ARM: dts: Add Freescale SAI ALSA SoC Digital Audio Interface node for VF610.
> > 'ARM: dts: vf610: ...' for patch prefix. > > Shawn Please see the next version. Thanks, -- Best Regards, Xiubo -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] w1: bundle reply if the request was bundled
A program can bundle multiple messages and commands together when making one wire requests, which is going to be much more efficient than sending lots of little packets one write at a time. With this change the kernel will then bundle responses to requests that were bundled, where it's probably even more important because programs will typically execute select or a poll operation between reading packets, which takes additional context switches. Without doing any bundling, reading 14 temperature sensors using slave commands requires the application to send 14 packets for the conversion with one command each, and then later for reading it takes 14 packets with two commands each, one to request reading the scratchpad, and another to read the data back in. The kernel will then generate 14 replies with data, and then one status for each of the three commands per sensor totaling 56 packets or 84 total packets. That's a lot of context switches and not very efficient on the one wire bus. Using master commands allows for merging writes, such as match rom, rom id, and convert temperature into sending one write to the hardware. But that means sending individual commands for reset and write (for convert), or reset, write, read (for reading the result) which would be 28 packets without bundling or 2 packets when bundling. It requires two packets because it must wait for the conversion before reading results. Without this change the kernel would send one read result, and five command status results, so 6*14 = 84 packets. With this set of changes it would send three, a set of status results for the first convert commands, and another status result along with the data read for the second set. This also allows an application to get all the results from a bundle (reading the temperature sensors) at the same time, instead of them being spread out in time as the one wire bus takes time to execute and read each response. Due to the data structure limitation this patch will return packets in a different order. For a given bundle all the replies will be sent first, followed by the status messages. This is because currently the connector takes a cn_msg, and the difference between a reply and status is the ack field of cn_msg. I could add a second cn_netlink_send_nlh, to take a nlmsghdr or maybe a length so multiple cn_msg can be bundled into one packet, then all the messages could be returned in the current order. --- drivers/w1/w1.h |8 - drivers/w1/w1_netlink.c | 531 ++- 2 files changed, 340 insertions(+), 199 deletions(-) diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index 734dab7..56a49ba 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h @@ -203,7 +203,6 @@ enum w1_master_flags { * @search_id: allows continuing a search * @refcnt:reference count * @priv: private data storage - * @priv_size: size allocated * @enable_pullup: allows a strong pullup * @pullup_duration: time for the next strong pullup * @flags: one of w1_master_flags @@ -214,7 +213,6 @@ enum w1_master_flags { * @dev: sysfs device * @bus_master:io operations available * @seq: sequence number used for netlink broadcasts - * @portid:destination for the current netlink command */ struct w1_master { @@ -241,7 +239,6 @@ struct w1_master atomic_trefcnt; void*priv; - int priv_size; /** 5V strong pullup enabled flag, 1 enabled, zero disabled. */ int enable_pullup; @@ -260,11 +257,6 @@ struct w1_master struct w1_bus_master*bus_master; u32 seq; - /* port id to send netlink responses to. The value is temporarily -* stored here while processing a message, set after locking the -* mutex, zero before unlocking the mutex. -*/ - u32 portid; }; /** diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c index fa24561..98b9314 100644 --- a/drivers/w1/w1_netlink.c +++ b/drivers/w1/w1_netlink.c @@ -29,6 +29,198 @@ #include "w1_netlink.h" #if defined(CONFIG_W1_CON) && (defined(CONFIG_CONNECTOR) || (defined(CONFIG_CONNECTOR_MODULE) && defined(CONFIG_W1_MODULE))) + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +/* Bundle together everything required to process a request in one memory + * allocation. + */ +struct w1_cb_block { + atomic_t refcnt; + /* replies, this would be include the data for a read message */ + /* maximum value for reply_msg->len */ + u16 reply_maxlen; + /* pointers to building up the reply message */ + struct cn_msg *reply_msg; + struct w1_netlink_msg *reply_m; + struct w1_netlink_cmd *reply_cmd; + /* status, for w1_netlink_msg.status of 0 success or error, ca
[BISECTED] Xen HVM guest hangs since 3.12-rc5
I've been running into problems on an Xen HVM domU. I've got a guest with NUMA enabled, 60GB of RAM, and 3 disks attached (including root volume). 2 of the disks are in an MD RAID0 in the guest, with an ext4 filesystem on top of that. I was running the fio 'iometer-file-access-server.fio' example config against that fs. During this workload, it would eventually cause a soft lockup, like the below: [ 2536.250054] BUG: soft lockup - CPU#0 stuck for 23s! [kworker/u257:0:7] [ 2536.250054] Modules linked in: isofs crct10dif_pclmul crct10dif_common crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd raid0 md_mod acpi_cpufreq psmouse i2c_piix4 intel_agp intel_gtt i2c_core processor serio_raw evdev microcode ext4 crc16 mbcache jbd2 ata_generic pata_acpi ata_piix libata scsi_mod floppy ixgbevf xen_privcmd xen_netfront xen_kbdfront syscopyarea sysfillrect sysimgblt fb_sys_fops xen_blkfront virtio_pci virtio_net virtio_blk virtio_ring virtio ipmi_poweroff ipmi_msghandler button [ 2536.250054] CPU: 0 PID: 7 Comm: kworker/u257:0 Tainted: GW 3.12.0-rc4-bisect-00073-g6fe6b2d #26 [ 2536.250054] Hardware name: Xen HVM domU, BIOS 4.2.amazon 01/14/2014 [ 2536.250054] Workqueue: writeback bdi_writeback_workfn (flush-202:0) [ 2536.250054] task: 880766533400 ti: 88076652e000 task.ti: 88076652e000 [ 2536.250054] RIP: 0010:[] [] smp_call_function_many+0x258/0x2b0 [ 2536.250054] RSP: 0018:88076652f878 EFLAGS: 0202 [ 2536.250054] RAX: 000f RBX: 88076652f808 RCX: 880ef0ef74a8 [ 2536.250054] RDX: 000f RSI: 0080 RDI: [ 2536.250054] RBP: 88076652f8c0 R08: 880771046c00 R09: 880770c008e0 [ 2536.250054] R10: 003e R11: 0210 R12: 88076652f7f0 [ 2536.250054] R13: 810b859e R14: 88076652f7e0 R15: 810b50e7 [ 2536.250054] FS: () GS:88077160() knlGS: [ 2536.250054] CS: 0010 DS: ES: CR0: 80050033 [ 2536.250054] CR2: 7f8752bea000 CR3: 01a0d000 CR4: 001406f0 [ 2536.250054] Stack: [ 2536.250054] 000181275231 00014d00 88076652f8d0 810564e0 [ 2536.250054] 88076530b180 7f0c8826a000 880ed4d57700 88076530b180 [ 2536.250054] 880ed4cc6350 88076652f8e8 81056637 88076530b180 [ 2536.250054] Call Trace: [ 2536.250054] [] ? leave_mm+0x70/0x70 [ 2536.250054] [] native_flush_tlb_others+0x37/0x40 [ 2536.250054] [] flush_tlb_page+0x88/0x90 [ 2536.250054] [] ptep_clear_flush+0x34/0x40 [ 2536.250054] [] page_mkclean+0x12e/0x1d0 [ 2536.250054] [] clear_page_dirty_for_io+0x3b/0xe0 [ 2536.250054] [] mpage_submit_page+0x52/0x80 [ext4] [ 2536.250054] [] mpage_process_page_bufs+0x109/0x140 [ext4] [ 2536.250054] [] mpage_prepare_extent_to_map+0x217/0x2d0 [ext4] [ 2536.250054] [] ext4_writepages+0x469/0xca0 [ext4] [ 2536.250054] [] do_writepages+0x1e/0x50 [ 2536.250054] [] __writeback_single_inode+0x76/0x240 [ 2536.250054] [] writeback_sb_inodes+0x282/0x420 [ 2536.250054] [] __writeback_inodes_wb+0x7f/0xd0 [ 2536.250054] [] wb_writeback+0x15b/0x2a0 [ 2536.250054] [] bdi_writeback_workfn+0x1d7/0x450 [ 2536.250054] [] process_one_work+0x25d/0x460 [ 2536.250054] [] worker_thread+0x266/0x480 [ 2536.250054] [] ? manage_workers.isra.18+0x3f0/0x3f0 [ 2536.250054] [] kthread+0xbb/0xd0 [ 2536.250054] [] ? kthread_stop+0xf0/0xf0 [ 2536.250054] [] ret_from_fork+0x7c/0xb0 [ 2536.250054] [] ? kthread_stop+0xf0/0xf0 [ 2536.250054] Code: 00 74 70 48 63 35 d1 1f a1 00 ba ff ff ff ff eb 29 66 90 48 98 48 8b 0b 48 03 0c c5 00 27 ad 81 f6 41 20 01 74 14 0f 1f 44 00 00 90 f6 41 20 01 75 f8 48 63 35 a1 1f a1 00 48 8b 7b 08 83 c2 [ 2544.900055] BUG: soft lockup - CPU#31 stuck for 24s! [systemd-journal:304] [ 2544.900055] Modules linked in: isofs crct10dif_pclmul crct10dif_common crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel aes_x86_64 lrw gf128mul glue_helper ablk_helper cryptd raid0 md_mod acpi_cpufreq psmouse i2c_piix4 intel_agp intel_gtt i2c_core processor serio_raw evdev microcode ext4 crc16 mbcache jbd2 ata_generic pata_acpi ata_piix libata scsi_mod floppy ixgbevf xen_privcmd xen_netfront xen_kbdfront syscopyarea sysfillrect sysimgblt fb_sys_fops xen_blkfront virtio_pci virtio_net virtio_blk virtio_ring virtio ipmi_poweroff ipmi_msghandler button [ 2544.900055] CPU: 31 PID: 304 Comm: systemd-journal Tainted: GW 3.12.0-rc4-bisect-00073-g6fe6b2d #26 [ 2544.900055] Hardware name: Xen HVM domU, BIOS 4.2.amazon 01/14/2014 [ 2544.900055] task: 880764bcb400 ti: 8807653f6000 task.ti: 8807653f6000 [ 2544.900055] RIP: 0010:[] [] generic_exec_single+0x80/0xa0 [ 2544.900055] RSP: 0018:8807653f7c80 EFLAGS: 0202 [ 2544.900055] RAX: 0080 RBX: 813207fd RCX: 0080 [ 2544.900055] RDX: 0001 RSI: R
Re: [PATCH 3/4] ARM: dts: Enable SGTL5000 codec based audio driver node for VF610 TOWER.
On Wed, Feb 19, 2014 at 01:38:42PM +0800, Xiubo Li wrote: > This patch adds and enables SGTL5000 codec support. > > Signed-off-by: Xiubo Li > --- > arch/arm/boot/dts/vf610-twr.dts | 19 +++ > 1 file changed, 19 insertions(+) > > diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts > index 8217854..29790c9 100644 > --- a/arch/arm/boot/dts/vf610-twr.dts > +++ b/arch/arm/boot/dts/vf610-twr.dts > @@ -34,6 +34,17 @@ > }; > }; > > + regulators { > + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <0>; > + > + reg_3p3v: 3p3v { reg_3p3v: regulator@0 { > + compatible = "regulator-fixed"; reg = <0>; Shawn > + regulator-name = "3P3V"; > + regulator-min-microvolt = <330>; > + regulator-max-microvolt = <330>; > + regulator-always-on; > + }; > + }; > }; > > &dspi0 { > @@ -72,6 +83,14 @@ > pinctrl-names = "default"; > pinctrl-0 = <&pinctrl_i2c0>; > status = "okay"; > + > + codec: sgtl5000@0a { > +compatible = "fsl,sgtl5000"; > +reg = <0x0a>; > +VDDA-supply = <®_3p3v>; > +VDDIO-supply = <®_3p3v>; > +clocks = <&clks VF610_CLK_SAI2>; > + }; > }; > > &iomuxc { > -- > 1.8.4 > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] gcov: fix memory allocation problem in gcov_info_dup
From: Yuan Pengfei If -fprofile-values option is used, ctr->num and sci_ptr->num may be zero, resulting in zero size and cv_size, which will cause ENOMEM when opening gcov data files in debugfs. Signed-off-by: Yuan Pengfei --- kernel/gcov/gcc_3_4.c | 2 +- kernel/gcov/gcc_4_7.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/gcov/gcc_3_4.c b/kernel/gcov/gcc_3_4.c index 27bc88a..1c1f425 100644 --- a/kernel/gcov/gcc_3_4.c +++ b/kernel/gcov/gcc_3_4.c @@ -269,7 +269,7 @@ struct gcov_info *gcov_info_dup(struct gcov_info *info) dup->counts[i].num = ctr->num; dup->counts[i].merge = ctr->merge; dup->counts[i].values = vmalloc(size); - if (!dup->counts[i].values) + if (size && !dup->counts[i].values) goto err_free; memcpy(dup->counts[i].values, ctr->values, size); } diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c index 2c6e463..7465944 100644 --- a/kernel/gcov/gcc_4_7.c +++ b/kernel/gcov/gcc_4_7.c @@ -290,7 +290,7 @@ struct gcov_info *gcov_info_dup(struct gcov_info *info) dci_ptr->values = vmalloc(cv_size); - if (!dci_ptr->values) + if (cv_size && !dci_ptr->values) goto err_free; dci_ptr->num = sci_ptr->num; -- 1.8.5.3
Re: [PATCH 2/4] ARM: dts: Enable SAI ALSA SoC DAI device for Vybrid VF610 TOWER board.
On Wed, Feb 19, 2014 at 01:38:41PM +0800, Xiubo Li wrote: > This patch adds and enables the SAI device. > > Signed-off-by: Xiubo Li The patch subject can be a little short like ARM: dts: vf610-twr: Enable SAI ALSA SoC DAI device Shawn > --- > arch/arm/boot/dts/vf610-twr.dts | 18 ++ > 1 file changed, 18 insertions(+) > > diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts > index e3a3805..8217854 100644 > --- a/arch/arm/boot/dts/vf610-twr.dts > +++ b/arch/arm/boot/dts/vf610-twr.dts > @@ -127,9 +127,27 @@ > VF610_PAD_PTB5__UART1_RX0x21a1 > >; > }; > + > + pinctrl_sai2: sai2grp { > + fsl,pins = < > + VF610_PAD_PTA16__SAI2_TX_BCLK 0x02ed > + VF610_PAD_PTA18__SAI2_TX_DATA 0x02ee > + VF610_PAD_PTA19__SAI2_TX_SYNC 0x02ed > + VF610_PAD_PTA21__SAI2_RX_BCLK 0x02ed > + VF610_PAD_PTA22__SAI2_RX_DATA 0x02ed > + VF610_PAD_PTA23__SAI2_RX_SYNC 0x02ed > + VF610_PAD_PTB18__EXT_AUDIO_MCLK 0x02ed > + >; > + }; > }; > }; > > +&sai2 { > + pinctrl-names = "default"; > + pinctrl-0 = <&pinctrl_sai2>; > + status = "okay"; > +}; > + > &uart1 { > pinctrl-names = "default"; > pinctrl-0 = <&pinctrl_uart1>; > -- > 1.8.4 > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: snd_intel8x0_inside_vm()
At Tue, 18 Feb 2014 19:48:11 -0800, H. Peter Anvin wrote: > > I just stumbled upon the function snd_intel8x0_inside_vm(), and quite > frankly the code seems bizarre: > > /* detect KVM and Parallels virtual environments */ > result = kvm_para_available(); > #ifdef X86_FEATURE_HYPERVISOR > result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR); > #endif > if (!result) > goto fini; > > Why don't we simply rely on the PCI SSIDs? The original code checking kvm_para_available() and boot_cpu_has() was supposed to work for also VirtualBox and VMware. The PCI SSID checks have been introduced later, and looking at the code again, this might have broken VirtualBox and VMware workaround. Hmm. Besides that, the kvm_para_available() and boot_cpu_has() checks are still left for avoiding unnecessary kernel message (enable/disable VM workaround) on non-VM kernels. Takashi -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 0/3] Deferrable timers support for timerfd API
On 02/19/2014 02:33 AM, Thomas Gleixner wrote: On Tue, 18 Feb 2014, Alexey Perevalov wrote: On 02/16/2014 07:39 PM, Thomas Gleixner wrote: I figured out with deviation, I described before. Which is wrong to begin with. Using the wrong method does not justify the results. Are you actually trying to understand what I'm saying? It was due expires and especially softexpires is fixed (don't base on delay). That's how an interval timer is supposed to work by definition. End of discussion. For example if we have a timer like this: hrtimer_expire_entry: hrtimer=a056f280 function=timerfd_tmrproc [hrtimers_mod] now=191450988244 expires=1914 softexpires=1914 It was fired at 191450988244, but softexpire is 1914, 50ms delay, if I'm not wrong. Next trigger time is 1917, (hrtimer_start: hrtimer=a056f280 function=timerfd_tmrproc [hrtimers_mod] expires=1917 softexpires=1917) and if there is no cpu idle at next time, we'll get 250ms interval for such timer. This is complete nonsense. You schedule your hrtimer on an absolute timeline: 1914 1917 ... So it's supposed to fire every 300ms, but it is allowed to fire later when the system is idle. And that's what it does. If the system would be idle for 10.3 seconds from the point where the timer is started then it would expire the first timer at 1914 + 10 sec = 2014 and then schedule the next one at 2014 + 300ms = 2017 So if your system is not idle the timer can be expired. That's the same for deferrable timer list timers. We expire them when a non deferrable timer fires. And you do the same for your timer list timer according to your trace: expires=4298169903 expires=4298169978 expires=4298170053 expires=4298170128 expires=4298170204 expires=4298170287 expires=4298170362 expires=4298170462 expires=4298170558 expires=4298170637 expires=4298170712 expires=4298170787 expires=4298170862 The delta is always 75 ticks. And the expiry times are now=4298169903 now=4298169978 now=4298170053 now=4298170129 now=4298170212 now=4298170287 now=4298170387 now=4298170483 now=4298170562 now=4298170637 now=4298170712 now=4298170787 Which results in the deferrements: Delta: 0.0ms Delta: 0.0ms Delta: 0.0ms Delta: 1.0ms Delta: 8.0ms Delta: 0.0ms Delta: 25.0ms Delta: 21.0ms Delta: 4.0ms Delta: 0.0ms Delta: 0.0ms Delta: 0.0ms Avg: 4.0ms And why? Because you scheduled your timer along an absolute timeline. And if you use an absolute timeline, then the deltas between the actual timer events are completely irrelevant. The only thing what matters is the delta between the expected and the real expiry time. Is it really that hard to understand? But we want 300ms or more for DEFERRABLE timer. And I want a pony! If you want that then simply setup the timer in relative oneshot mode, i.e. interval = 0 and when it expires (deferred) rearm it relative to now from user space. Then you get exactly the behaviour you want. It's that simple, really. Thomas what do you think about moving format expire/softexpire to _!now!_ in run_hrtimer, right before we invoke callback function? The prolongation of hrtimer usually comes from user timer functions by invoking hrtimer_forward, which moves expires/softexpires forward. You really don't want to know what I think about that. + trace_hrtimer_expire_entry(timer, now, 0); + + if (deferrable) + hrtimer_set_expires(timer, *now); restart = fn(timer); I got expected results (timer interval is 300ms): So you got your pony. But it's your private pony and it stays that way, because you made the timer interval relative. And you managed to do that in the most disgusting way. In course of that you broke the behaviour of the existing user space interfaces. You can do so in your own hackery, but it's not going to go near mainline. Read and understand: man timer_create man timerfd along with the relevant standards. And if you need further education feel free to get a lecture from Linus about user space interfaces or google one if you really want to know how that works out. We are not going to special case that deferrable stuff, simply because it breaks the user space interfaces and you can solve your issue with the existing user space interfaces already. There is a simple solution for the problem. You just need to understand what you try to solve and use the proper mechanisms. And don't tell me you can't do that, because you need to modify your user space code anyway as CLOCK*DEFERRABLE does not exist yet. In that the whole point CLOCK*DEFERRABLE doesn't exist yet, and such reset of timer's expire didn't affect another clockids. Ok no problem, to set new expire time based on _now_ from user space. Just because you can do it in the kernel does not mean that it is the correct approach. Thanks, tglx -- Best regards, Alexey Perevalov -- To unsubscribe fr
Re: [PATCH 1/4] ARM: dts: Add Freescale SAI ALSA SoC Digital Audio Interface node for VF610.
On Wed, Feb 19, 2014 at 01:38:40PM +0800, Xiubo Li wrote: > This patch adds the SAI's edma mux Tx and Rx support. > > Signed-off-by: Xiubo Li 'ARM: dts: vf610: ...' for patch prefix. Shawn > --- > arch/arm/boot/dts/vf610.dtsi | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi > index 91a7757..f08df47 100644 > --- a/arch/arm/boot/dts/vf610.dtsi > +++ b/arch/arm/boot/dts/vf610.dtsi > @@ -169,6 +169,9 @@ > interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>; > clocks = <&clks VF610_CLK_SAI2>; > clock-names = "sai"; > + dma-names = "tx", "rx"; > + dmas = <&edma0 0 21>, > + <&edma0 0 20>; > status = "disabled"; > }; > > -- > 1.8.4 > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/4] ARM: dts: Enable SAI ALSA SoC DAI device for Vybrid VF610 TOWER board.
On Wed, Feb 19, 2014 at 01:38:41PM +0800, Xiubo Li wrote: > This patch adds and enables the SAI device. > > Signed-off-by: Xiubo Li > --- > arch/arm/boot/dts/vf610-twr.dts | 18 ++ > 1 file changed, 18 insertions(+) > > diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts > index e3a3805..8217854 100644 > --- a/arch/arm/boot/dts/vf610-twr.dts > +++ b/arch/arm/boot/dts/vf610-twr.dts > @@ -127,9 +127,27 @@ > VF610_PAD_PTB5__UART1_RX0x21a1 > >; > }; > + > + pinctrl_sai2: sai2grp { To sort it alphabetically, the entry should be added before pinctrl_uart1. > + fsl,pins = < > + VF610_PAD_PTA16__SAI2_TX_BCLK 0x02ed > + VF610_PAD_PTA18__SAI2_TX_DATA 0x02ee > + VF610_PAD_PTA19__SAI2_TX_SYNC 0x02ed > + VF610_PAD_PTA21__SAI2_RX_BCLK 0x02ed > + VF610_PAD_PTA22__SAI2_RX_DATA 0x02ed > + VF610_PAD_PTA23__SAI2_RX_SYNC 0x02ed > + VF610_PAD_PTB18__EXT_AUDIO_MCLK 0x02ed Use tabs instead of spaces. Shawn > + >; > + }; > }; > }; > > +&sai2 { > + pinctrl-names = "default"; > + pinctrl-0 = <&pinctrl_sai2>; > + status = "okay"; > +}; > + > &uart1 { > pinctrl-names = "default"; > pinctrl-0 = <&pinctrl_uart1>; > -- > 1.8.4 > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v4 0/3] qspinlock: Introducing a 4-byte queue spinlock
On 02/19/2014 06:12 AM, Waiman Long wrote: On 02/18/2014 04:28 PM, Peter Zijlstra wrote: On Tue, Feb 18, 2014 at 02:30:12PM -0500, Waiman Long wrote: I will start looking at how to make it work with paravirt. Hopefully, it won't take too long. The cheap way out is to simply switch to the test-and-set spinlock on whatever X86_FEATURE_ indicates a guest I suppose. I don't think there is X86_FEATURE flag that indicates running in a guest. In fact, a guest should never find out if it is running virtualized. After reading the current PV ticketlock implementation, I have a rough idea of what I need to do to implement PV support in qspinlock. A large portion of PV ticketlock code is find out the CPU number of the next one to get the lock. The current qspinlock implementation has already included CPU number of the previous member in the queue and it should be pretty easy to store CPU number of the next one in the queue node structure. These CPU numbers can then be supplied to the kick_cpu() function to schedule in the require the CPU to make sure that progress can be made. That is correct. Strict serialization of the lock is usually a headache for virtualized guest (especially when overcommitted). I am eager to test the next version. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC PATCH] rcu: move SRCU grace period work to power efficient workqueue
On Mon, 2014-02-17 at 05:50 +0100, Mike Galbraith wrote: > On Sun, 2014-02-16 at 08:41 -0800, Paul E. McKenney wrote: > > So maybe start with Kevin's patch, but augment with something else for > > the !NO_HZ_FULL case? > > Sure (hm, does it work without workqueue.disable_numa ?). I took patch out for a spin on a 40 core box +SMT, with CPUs 4-79 isolated via exclusive cpuset with load balancing off. Worker bees ignored patch either way. -Mike Perturbation measurement hog pinned to CPU4. With patch: # TASK-PID CPU# || TIMESTAMP FUNCTION # | | | || | | pert-9949 [004] 113 405.120164: workqueue_queue_work: work struct=880a5c4ecc08 function=flush_to_ldisc workqueue=88046f40ba00 req_cpu=256 cpu=4 pert-9949 [004] 113 405.120166: workqueue_activate_work: work struct 880a5c4ecc08 pert-9949 [004] d.L.313 405.120169: sched_wakeup: comm=kworker/4:2 pid=2119 prio=120 success=1 target_cpu=004 pert-9949 [004] d.Lh213 405.120170: tick_stop: success=no msg=more than 1 task in runqueue pert-9949 [004] d.L.213 405.120172: tick_stop: success=no msg=more than 1 task in runqueue pert-9949 [004] d...3.. 405.120173: sched_switch: prev_comm=pert prev_pid=9949 prev_prio=120 prev_state=R+ ==> next_comm=kworker/4:2 next_pid=2119 next_prio=120 kworker/4:2-2119 [004] 1.. 405.120174: workqueue_execute_start: work struct 880a5c4ecc08: function flush_to_ldisc kworker/4:2-2119 [004] d...311 405.120176: sched_wakeup: comm=sshd pid=6620 prio=120 success=1 target_cpu=000 kworker/4:2-2119 [004] 1.. 405.120176: workqueue_execute_end: work struct 880a5c4ecc08 kworker/4:2-2119 [004] d...3.. 405.120177: sched_switch: prev_comm=kworker/4:2 prev_pid=2119 prev_prio=120 prev_state=S ==> next_comm=pert next_pid=9949 next_prio=120 pert-9949 [004] 113 405.120178: workqueue_queue_work: work struct=880a5c4ecc08 function=flush_to_ldisc workqueue=88046f40ba00 req_cpu=256 cpu=4 pert-9949 [004] 113 405.120179: workqueue_activate_work: work struct 880a5c4ecc08 pert-9949 [004] d.L.313 405.120179: sched_wakeup: comm=kworker/4:2 pid=2119 prio=120 success=1 target_cpu=004 pert-9949 [004] d.L.213 405.120181: tick_stop: success=no msg=more than 1 task in runqueue pert-9949 [004] d...3.. 405.120181: sched_switch: prev_comm=pert prev_pid=9949 prev_prio=120 prev_state=R+ ==> next_comm=kworker/4:2 next_pid=2119 next_prio=120 kworker/4:2-2119 [004] 1.. 405.120182: workqueue_execute_start: work struct 880a5c4ecc08: function flush_to_ldisc kworker/4:2-2119 [004] 1.. 405.120183: workqueue_execute_end: work struct 880a5c4ecc08 kworker/4:2-2119 [004] d...3.. 405.120183: sched_switch: prev_comm=kworker/4:2 prev_pid=2119 prev_prio=120 prev_state=S ==> next_comm=pert next_pid=9949 next_prio=120 pert-9949 [004] d...1.. 405.120736: tick_stop: success=yes msg= pert-9949 [004] 113 410.121082: workqueue_queue_work: work struct=880a5c4ecc08 function=flush_to_ldisc workqueue=88046f40ba00 req_cpu=256 cpu=4 pert-9949 [004] 113 410.121082: workqueue_activate_work: work struct 880a5c4ecc08 pert-9949 [004] d.L.313 410.121084: sched_wakeup: comm=kworker/4:2 pid=2119 prio=120 success=1 target_cpu=004 pert-9949 [004] d.Lh213 410.121085: tick_stop: success=no msg=more than 1 task in runqueue pert-9949 [004] d.L.213 410.121087: tick_stop: success=no msg=more than 1 task in runqueue ...and so on until tick time (extra cheezy) hack kinda sorta works iff workqueue.disable_numa: --- kernel/workqueue.c |5 - 1 file changed, 4 insertions(+), 1 deletion(-) --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -1328,8 +1328,11 @@ static void __queue_work(int cpu, struct rcu_read_lock(); retry: - if (req_cpu == WORK_CPU_UNBOUND) + if (req_cpu == WORK_CPU_UNBOUND) { cpu = raw_smp_processor_id(); + if (runqueue_is_isolated(cpu)) + cpu = 0; + } /* pwq which will be used unless @work is executing elsewhere */ if (!(wq->flags & WQ_UNBOUND)) # TASK-PID CPU# || TIMESTAMP FUNCTION # | | | || | | <...>-33824 [004] 113 .889694: workqueue_queue_work: work struct=880a596eb008 function=flush_to_ldisc workqueue=88046f40ba00 req_cpu=256 cpu=0 <...>-33824 [004] 113 .889695: workqueue_activate_work: work struct 880a596eb008 <...>-33824 [004] d...313 .889697: sched_wakeup: comm=kworker/0:2 pid=2105 prio=120 success=1 target_cpu=000 <...>-33824 [004] 113 5560.890594: wor
mm: OS boot failed when set command-line kmemcheck=1
Hi all, CONFIG_KMEMCHECK=y and set command-line "kmemcheck=1", I find OS boot failed. The kernel is v3.14.0-rc3 If set "kmemcheck=1 nowatchdog", OS will boot successfully. Here is the boot failed log: [ 23.586826] Freeing unused kernel memory: 1160K (8800014de000 - 88000 160) [ 23.600248] Freeing unused kernel memory: 1696K (880001858000 - 88000 1a0) [ 23.615534] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00 05 [ 23.615534] [ 23.624885] CPU: 0 PID: 1 Comm: init Tainted: GW3.14.0-rc3-0.1-de fault+ #1 [ 23.632957] Hardware name: Huawei Technologies Co., Ltd. Tecal RH2285 /BC11BTSA , BIOS CTSAV036 04/27/2011 [ 23.644661] 880c1dd28000 880c1dd31c48 814ca491 880c1dd31 cc8 [ 23.652416] 814ca1e6 0010 880c1dd31cd8 880c1dd31 c78 [ 23.660171] 0027 880c1dcb8280 0005 880c1dd28 000 [ 23.667931] Call Trace: [ 23.670482] [] dump_stack+0x6a/0x79 [ 23.675712] [] panic+0xb9/0x1f4 [ 23.680599] [] forget_original_parent+0x42e/0x430 [ 23.687043] [] ? perf_cgroup_switch+0x170/0x170 [ 23.693314] [] exit_notify+0x11/0x140 [ 23.698722] [] do_exit+0x230/0x490 [ 23.703865] [] do_group_exit+0x43/0xb0 [ 23.709357] [] get_signal_to_deliver+0x241/0x4b0 [ 23.715713] [] do_notify_resume+0xac/0x1a0 [ 23.721551] [] int_signal+0x12/0x17 [ 23.726786] Kernel Offset: 0x0 from 0x8100 (relocation range: 0xf fff8000-0x9fff) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] ALSA: hda/ca0132 - setup/cleanup streams
At Wed, 19 Feb 2014 14:27:07 +0800, Hsin-Yu Chao wrote: > > When a HDMI stream is opened with the same stream tag > as a following opened stream to ca0132, audio will be > heard from two ports simultaneously. > Fix this issue by change to use snd_hda_codec_setup_stream > and snd_hda_codec_cleanup_stream instead, so that an > inactive stream can be marked as 'dirty' when found > with a conflict stream tag, and then get purified. > > Signed-off-by: Hsin-Yu Chao > Reviewed-by: Chih-Chung Chang Thanks, I applied both patches now with Cc to stable. Takashi > --- > sound/pci/hda/patch_ca0132.c | 66 > +--- > 1 file changed, 7 insertions(+), 59 deletions(-) > > diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c > index 54d1479..0aa72ee 100644 > --- a/sound/pci/hda/patch_ca0132.c > +++ b/sound/pci/hda/patch_ca0132.c > @@ -2662,60 +2662,6 @@ static bool dspload_wait_loaded(struct hda_codec > *codec) > } > > /* > - * PCM stuffs > - */ > -static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, > - u32 stream_tag, > - int channel_id, int format) > -{ > - unsigned int oldval, newval; > - > - if (!nid) > - return; > - > - snd_printdd( > -"ca0132_setup_stream: NID=0x%x, stream=0x%x, " > -"channel=%d, format=0x%x\n", > -nid, stream_tag, channel_id, format); > - > - /* update the format-id if changed */ > - oldval = snd_hda_codec_read(codec, nid, 0, > - AC_VERB_GET_STREAM_FORMAT, > - 0); > - if (oldval != format) { > - msleep(20); > - snd_hda_codec_write(codec, nid, 0, > - AC_VERB_SET_STREAM_FORMAT, > - format); > - } > - > - oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); > - newval = (stream_tag << 4) | channel_id; > - if (oldval != newval) { > - snd_hda_codec_write(codec, nid, 0, > - AC_VERB_SET_CHANNEL_STREAMID, > - newval); > - } > -} > - > -static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) > -{ > - unsigned int val; > - > - if (!nid) > - return; > - > - snd_printdd(KERN_INFO "ca0132_cleanup_stream: NID=0x%x\n", nid); > - > - val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); > - if (!val) > - return; > - > - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); > - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); > -} > - > -/* > * PCM callbacks > */ > static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, > @@ -2726,7 +2672,7 @@ static int ca0132_playback_pcm_prepare(struct > hda_pcm_stream *hinfo, > { > struct ca0132_spec *spec = codec->spec; > > - ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); > + snd_hda_codec_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); > > return 0; > } > @@ -2745,7 +2691,7 @@ static int ca0132_playback_pcm_cleanup(struct > hda_pcm_stream *hinfo, > if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) > msleep(50); > > - ca0132_cleanup_stream(codec, spec->dacs[0]); > + snd_hda_codec_cleanup_stream(codec, spec->dacs[0]); > > return 0; > } > @@ -2824,8 +2770,8 @@ static int ca0132_capture_pcm_prepare(struct > hda_pcm_stream *hinfo, > { > struct ca0132_spec *spec = codec->spec; > > - ca0132_setup_stream(codec, spec->adcs[substream->number], > - stream_tag, 0, format); > + snd_hda_codec_setup_stream(codec, spec->adcs[substream->number], > +stream_tag, 0, format); > > return 0; > } > @@ -2839,7 +2785,7 @@ static int ca0132_capture_pcm_cleanup(struct > hda_pcm_stream *hinfo, > if (spec->dsp_state == DSP_DOWNLOADING) > return 0; > > - ca0132_cleanup_stream(codec, hinfo->nid); > + snd_hda_codec_cleanup_stream(codec, hinfo->nid); > return 0; > } > > @@ -4742,6 +4688,8 @@ static int patch_ca0132(struct hda_codec *codec) > return err; > > codec->patch_ops = ca0132_patch_ops; > + codec->pcm_format_first = 1; > + codec->no_sticky_stream = 1; > > return 0; > } > -- > 1.8.3.2 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/4] ARM: dts: Add simple-card support for Vybird-TWR board
This patch adds and enables simple-card support in DT node. Signed-off-by: Xiubo Li --- arch/arm/boot/dts/vf610-twr.dts | 31 +++ 1 file changed, 31 insertions(+) diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts index 29790c9..ff27dce 100644 --- a/arch/arm/boot/dts/vf610-twr.dts +++ b/arch/arm/boot/dts/vf610-twr.dts @@ -45,6 +45,35 @@ regulator-always-on; }; }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Speaker", "Speaker Ext", + "Line", "Line In Jack"; + simple-audio-card,routing = + "MIC_IN", "Microphone Jack", + "Microphone Jack", "Mic Bias", + "LINE_IN", "Line In Jack", + "Headphone Jack", "HP_OUT", + "Speaker Ext", "LINE_OUT"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + master-clkdir-out; + frame-master; + bitclock-master; + }; + + simple-audio-card,codec { + sound-dai = <&codec>; + frame-master; + bitclock-master; + }; + }; }; &dspi0 { @@ -85,6 +114,7 @@ status = "okay"; codec: sgtl5000@0a { + #sound-dai-cells = <0>; compatible = "fsl,sgtl5000"; reg = <0x0a>; VDDA-supply = <®_3p3v>; @@ -162,6 +192,7 @@ }; &sai2 { + #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai2>; status = "okay"; -- 1.8.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/4] ARM: dts: Enable SGTL5000 codec based audio driver node for VF610 TOWER.
This patch adds and enables SGTL5000 codec support. Signed-off-by: Xiubo Li --- arch/arm/boot/dts/vf610-twr.dts | 19 +++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts index 8217854..29790c9 100644 --- a/arch/arm/boot/dts/vf610-twr.dts +++ b/arch/arm/boot/dts/vf610-twr.dts @@ -34,6 +34,17 @@ }; }; + regulators { + compatible = "simple-bus"; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + regulator-always-on; + }; + }; }; &dspi0 { @@ -72,6 +83,14 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c0>; status = "okay"; + + codec: sgtl5000@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + VDDA-supply = <®_3p3v>; + VDDIO-supply = <®_3p3v>; + clocks = <&clks VF610_CLK_SAI2>; + }; }; &iomuxc { -- 1.8.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/4] Add audio card support for Vybird-TWR board
Add audio card support for Vybird-TWR board Xiubo Li (4): ARM: dts: Add Freescale SAI ALSA SoC Digital Audio Interface node for VF610. ARM: dts: Enable SAI ALSA SoC DAI device for Vybrid VF610 TOWER board. ARM: dts: Enable SGTL5000 codec based audio driver node for VF610 TOWER. ARM: dts: Add simple-card support for Vybird-TWR board arch/arm/boot/dts/vf610-twr.dts | 68 + arch/arm/boot/dts/vf610.dtsi| 3 ++ 2 files changed, 71 insertions(+) -- 1.8.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/4] ARM: dts: Add Freescale SAI ALSA SoC Digital Audio Interface node for VF610.
This patch adds the SAI's edma mux Tx and Rx support. Signed-off-by: Xiubo Li --- arch/arm/boot/dts/vf610.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index 91a7757..f08df47 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -169,6 +169,9 @@ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks VF610_CLK_SAI2>; clock-names = "sai"; + dma-names = "tx", "rx"; + dmas = <&edma0 0 21>, + <&edma0 0 20>; status = "disabled"; }; -- 1.8.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/4] ARM: dts: Enable SAI ALSA SoC DAI device for Vybrid VF610 TOWER board.
This patch adds and enables the SAI device. Signed-off-by: Xiubo Li --- arch/arm/boot/dts/vf610-twr.dts | 18 ++ 1 file changed, 18 insertions(+) diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts index e3a3805..8217854 100644 --- a/arch/arm/boot/dts/vf610-twr.dts +++ b/arch/arm/boot/dts/vf610-twr.dts @@ -127,9 +127,27 @@ VF610_PAD_PTB5__UART1_RX0x21a1 >; }; + + pinctrl_sai2: sai2grp { + fsl,pins = < + VF610_PAD_PTA16__SAI2_TX_BCLK 0x02ed + VF610_PAD_PTA18__SAI2_TX_DATA 0x02ee + VF610_PAD_PTA19__SAI2_TX_SYNC 0x02ed + VF610_PAD_PTA21__SAI2_RX_BCLK 0x02ed + VF610_PAD_PTA22__SAI2_RX_DATA 0x02ed + VF610_PAD_PTA23__SAI2_RX_SYNC 0x02ed + VF610_PAD_PTB18__EXT_AUDIO_MCLK 0x02ed + >; + }; }; }; +&sai2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2>; + status = "okay"; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; -- 1.8.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/1] fs: xattr: Don't display attributes without read access
On Tue, 18 Feb 2014 15:16:50 -0800 Andrew Morton wrote: > On Sun, 16 Feb 2014 20:31:01 +0800 Fabian Frederick wrote: > > > Any user can display extented attribute names without read > > access. > > > > eg: attr -l > > > > This patch checks inode_permission in listxattr common > > function before executing vfs_listxattr. > > > > ... > > > > --- a/fs/xattr.c > > +++ b/fs/xattr.c > > @@ -543,6 +543,10 @@ listxattr(struct dentry *d, char __user *list, size_t > > size) > > char *klist = NULL; > > char *vlist = NULL; /* If non-NULL, we used vmalloc() */ > > > > + error = inode_permission(d->d_inode, MAY_READ); > > + if (error) > > + return error; > > + > > if (size) { > > if (size > XATTR_LIST_MAX) > > size = XATTR_LIST_MAX; > > erk. Doesn't this mean that if existing userspace is relying on the > current behaviour, this patch will cause breakage? > IMHO userspace applications already receive weird results in that case. Without read permission, attr -l receives attribute names which means it tries lgetxattr on those attributes where result is EACCESS : "Attribute has -1 byte" !!! Besides, is it semantically correct for a user to have access to a part of "file content" without read access ? With that patch, attr -l displays attr_list: Permission denied Could not list "(null)" for On the other hand, when stracing that situation, I do see attr making more noise than usual ie it's opening all attr.mo twice so I guess I should return something else than "permission denied" to avoid problems in userspace ... Fabian -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Unkillable R-state process stuck in sendfile
On 02/18/2014 11:13 PM, valdis.kletni...@vt.edu wrote: > On Mon, 17 Feb 2014 16:51:37 +0400, Vladimir Davydov said: > >> out_fd = eventfd(0, 0); >> if (out_fd < 0) >> err(1, "eventfd"); >> ret = sendfile64(out_fd, in_fd, NULL, SIZE); >> I'm not sure if this is actually bad and should be fixed, but perhaps >> it's worth making do_generic_file_read() check for fatal signals pending >> and break the read loop if so? > Why do we even allow an eventfd to be fed to sendfile64 at all? What > does that even *mean*? I guess it's meaningless, so another fix (if this should be fixed at all) would be disabling splice to eventfd. However, I cannot be 100%-sure nobody splices data to eventfd... Thanks. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] ALSA: hda/ca0132 - setup/cleanup streams
When a HDMI stream is opened with the same stream tag as a following opened stream to ca0132, audio will be heard from two ports simultaneously. Fix this issue by change to use snd_hda_codec_setup_stream and snd_hda_codec_cleanup_stream instead, so that an inactive stream can be marked as 'dirty' when found with a conflict stream tag, and then get purified. Signed-off-by: Hsin-Yu Chao Reviewed-by: Chih-Chung Chang --- sound/pci/hda/patch_ca0132.c | 66 +--- 1 file changed, 7 insertions(+), 59 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 54d1479..0aa72ee 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -2662,60 +2662,6 @@ static bool dspload_wait_loaded(struct hda_codec *codec) } /* - * PCM stuffs - */ -static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, -u32 stream_tag, -int channel_id, int format) -{ - unsigned int oldval, newval; - - if (!nid) - return; - - snd_printdd( - "ca0132_setup_stream: NID=0x%x, stream=0x%x, " - "channel=%d, format=0x%x\n", - nid, stream_tag, channel_id, format); - - /* update the format-id if changed */ - oldval = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_STREAM_FORMAT, - 0); - if (oldval != format) { - msleep(20); - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_STREAM_FORMAT, - format); - } - - oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); - newval = (stream_tag << 4) | channel_id; - if (oldval != newval) { - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_CHANNEL_STREAMID, - newval); - } -} - -static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) -{ - unsigned int val; - - if (!nid) - return; - - snd_printdd(KERN_INFO "ca0132_cleanup_stream: NID=0x%x\n", nid); - - val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); - if (!val) - return; - - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); -} - -/* * PCM callbacks */ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, @@ -2726,7 +2672,7 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, { struct ca0132_spec *spec = codec->spec; - ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); + snd_hda_codec_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); return 0; } @@ -2745,7 +2691,7 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) msleep(50); - ca0132_cleanup_stream(codec, spec->dacs[0]); + snd_hda_codec_cleanup_stream(codec, spec->dacs[0]); return 0; } @@ -2824,8 +2770,8 @@ static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo, { struct ca0132_spec *spec = codec->spec; - ca0132_setup_stream(codec, spec->adcs[substream->number], - stream_tag, 0, format); + snd_hda_codec_setup_stream(codec, spec->adcs[substream->number], + stream_tag, 0, format); return 0; } @@ -2839,7 +2785,7 @@ static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, if (spec->dsp_state == DSP_DOWNLOADING) return 0; - ca0132_cleanup_stream(codec, hinfo->nid); + snd_hda_codec_cleanup_stream(codec, hinfo->nid); return 0; } @@ -4742,6 +4688,8 @@ static int patch_ca0132(struct hda_codec *codec) return err; codec->patch_ops = ca0132_patch_ops; + codec->pcm_format_first = 1; + codec->no_sticky_stream = 1; return 0; } -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 4/4] of: Add self test for of_match_node()
On Tue, Feb 18, 2014 at 10:31:20PM +, Grant Likely wrote: > Adds a selftest function for the of_match_node function. of_match_node > is supposed to handle precedence for the compatible property as well as > the name and device_type values. This patch adds some test case data and > a function that makes sure each test node matches against the correct > entry of an of_device_id table. > > This code was written to verify the new of_match_node() implementation > that is an earlier part of this series. > > Currently all but one test passes. There is one scenario where the empty > "b/name2" node is getting matched against an entry without any > device_type property at all. It is unknown why this is, but it needs to > be solved before this patch can be committed. (However, this is testing > the new of_match_table implementation, which still does far better than > the old implementation which gets the precedence completely wrong.) We can drop the above paragraph now since all the test cases passed on the new version of of_match_node(). > > Signed-off-by: Grant Likely > Cc: Kevin Hau s/Hau/Hao/ Thanks, Kevin pgpkAgTjm8Qe_.pgp Description: PGP signature
[PATCH RESEND 2/2] clk: clk-s2mps11: Add support for clocks in S5M8767 MFD
Since clock operation within S2MPS11 and S5M8767 are similar, we can support both the devices within a single driver. Signed-off-by: Tushar Behera Reviewed-by: Tomasz Figa Reviewed-by: Yadwinder Singh Brar --- drivers/clk/Kconfig |6 -- drivers/clk/clk-s2mps11.c |5 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7641965..da1b416 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -65,10 +65,12 @@ config COMMON_CLK_SI570 clock generators. config COMMON_CLK_S2MPS11 - tristate "Clock driver for S2MPS11 MFD" + tristate "Clock driver for S2MPS11/S5M8767 MFD" depends on MFD_SEC_CORE ---help--- - This driver supports S2MPS11 crystal oscillator clock. + This driver supports S2MPS11/S5M8767 crystal oscillator clock. These + multi-function devices have 3 fixed-rate oscillators, clocked at + 32KHz each. config CLK_TWL6040 tristate "External McPDM functional clock from twl6040" diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 6f587bc..5088755 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #define s2mps11_name(a) (a->hw.init->name) @@ -175,6 +176,9 @@ static int s2mps11_clk_probe(struct platform_device *pdev) case S2MPS11X: s2mps11_reg = S2MPS11_REG_RTC_CTRL; break; + case S5M8767X: + s2mps11_reg = S5M8767_REG_CTRL1; + break; default: dev_err(&pdev->dev, "Invalid device type\n"); return -EINVAL; @@ -254,6 +258,7 @@ static int s2mps11_clk_remove(struct platform_device *pdev) static const struct platform_device_id s2mps11_clk_id[] = { { "s2mps11-clk", S2MPS11X}, + { "s5m8767-clk", S5M8767X}, { }, }; MODULE_DEVICE_TABLE(platform, s2mps11_clk_id); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 0/2] Add support for clocks in S5M8767
S5M8767 chip has 3 crystal oscillators which are operated in the same as the crystal oscillators in S2MPS11. Extend s2mps11-clk driver to support clocks in S5M8767. The patches are rebased on top of next-20130218. Tushar Behera (2): clk: clk-s2mps11: Refactor for including support for other MFD clocks clk: clk-s2mps11: Add support for clocks in S5M8767 MFD drivers/clk/Kconfig |6 -- drivers/clk/clk-s2mps11.c | 25 + 2 files changed, 25 insertions(+), 6 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] ALSA: hda/ca0132 - Fix recording from mode id 0x8
Incorrect ADC is picked in ca0132_capture_pcm_prepare(), where it assumes multiple streams while there is one stream per ADC. Note that ca0132_capture_pcm_cleanup() already does the right thing. The Chromebook Pixel has a microphone under the keyboard that is attached to node id 0x8. Before this fix, recording would always go to the main internal mic (node id 0x7). Signed-off-by: Hsin-Yu Chao Reviewed-by: Dylan Reid --- sound/pci/hda/patch_ca0132.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 0aa72ee..46ecdbb 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -2768,9 +2768,7 @@ static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo, unsigned int format, struct snd_pcm_substream *substream) { - struct ca0132_spec *spec = codec->spec; - - snd_hda_codec_setup_stream(codec, spec->adcs[substream->number], + snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format); return 0; -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH V2 1/2] clk: clk-s2mps11: Refactor for including support for other MFD clocks
The clocks in S2MPS11 and S5M8767 are managed in the same way, baring a difference in the register offset. It would be better to update existing S2MPS11 driver to support the clocks in S5M8767, rather than to create an almost duplicate driver altogether. Signed-off-by: Tushar Behera Reviewed-by: Tomasz Figa Reviewed-by: Yadwinder Singh Brar --- Changes since V1: * Fixed a check patch warning drivers/clk/clk-s2mps11.c | 20 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index 00a3abe..6f587bc 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -48,6 +48,7 @@ struct s2mps11_clk { struct clk_lookup *lookup; u32 mask; bool enabled; + unsigned int reg; }; static struct s2mps11_clk *to_s2mps11_clk(struct clk_hw *hw) @@ -61,7 +62,7 @@ static int s2mps11_clk_prepare(struct clk_hw *hw) int ret; ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, - S2MPS11_REG_RTC_CTRL, +s2mps11->reg, s2mps11->mask, s2mps11->mask); if (!ret) s2mps11->enabled = true; @@ -74,7 +75,7 @@ static void s2mps11_clk_unprepare(struct clk_hw *hw) struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw); int ret; - ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, S2MPS11_REG_RTC_CTRL, + ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, s2mps11->reg, s2mps11->mask, ~s2mps11->mask); if (!ret) @@ -155,6 +156,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev) struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; struct device_node *clk_np = NULL; + unsigned int s2mps11_reg; int i, ret = 0; u32 val; @@ -169,13 +171,23 @@ static int s2mps11_clk_probe(struct platform_device *pdev) if (IS_ERR(clk_np)) return PTR_ERR(clk_np); + switch (platform_get_device_id(pdev)->driver_data) { + case S2MPS11X: + s2mps11_reg = S2MPS11_REG_RTC_CTRL; + break; + default: + dev_err(&pdev->dev, "Invalid device type\n"); + return -EINVAL; + }; + for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) { s2mps11_clk->iodev = iodev; s2mps11_clk->hw.init = &s2mps11_clks_init[i]; s2mps11_clk->mask = 1 << i; + s2mps11_clk->reg = s2mps11_reg; ret = regmap_read(s2mps11_clk->iodev->regmap_pmic, - S2MPS11_REG_RTC_CTRL, &val); + s2mps11_clk->reg, &val); if (ret < 0) goto err_reg; @@ -241,7 +253,7 @@ static int s2mps11_clk_remove(struct platform_device *pdev) } static const struct platform_device_id s2mps11_clk_id[] = { - { "s2mps11-clk", 0}, + { "s2mps11-clk", S2MPS11X}, { }, }; MODULE_DEVICE_TABLE(platform, s2mps11_clk_id); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/3] sh: push extra copy of r0-r2 for syscall parameters
The userspace registers are stored at the top of the stack when the syscall handler is invoked, which allows r0-r2 to act as parameters 5-7. Parameters passed on the stack may be clobbered by the syscall handler. The solution is to push an extra copy of the registers which might be used as syscall parameters to the stack, so that the authoritative set of saved register values does not get clobbered. A few system call handlers are also updated to get the userspace registers using current_pt_regs() instead of from the stack. Signed-off-by: Bobby Bingham --- arch/sh/include/asm/syscalls_32.h | 12 +++- arch/sh/kernel/entry-common.S | 15 +++ arch/sh/kernel/signal_32.c| 12 arch/sh/kernel/sys_sh32.c | 7 ++- 4 files changed, 20 insertions(+), 26 deletions(-) diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h index 4f97df8..4f643aa 100644 --- a/arch/sh/include/asm/syscalls_32.h +++ b/arch/sh/include/asm/syscalls_32.h @@ -9,15 +9,9 @@ struct pt_regs; -asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, -unsigned long r6, unsigned long r7, -struct pt_regs __regs); -asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); -asmlinkage int sys_sh_pipe(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); +asmlinkage int sys_sigreturn(void); +asmlinkage int sys_rt_sigreturn(void); +asmlinkage int sys_sh_pipe(void); asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char __user *buf, size_t count, long dummy, loff_t pos); asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char __user *buf, diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index ca46834..13047a4 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -193,10 +193,10 @@ syscall_trace_entry: ! Reload R0-R4 from kernel stack, where the ! parent may have modified them using ! ptrace(POKEUSR). (Note that R0-R2 are - ! used by the system call handler directly - ! from the kernel stack anyway, so don't need - ! to be reloaded here.) This allows the parent - ! to rewrite system calls and args on the fly. + ! reloaded from the kernel stack by syscall_call + ! below, so don't need to be reloaded here.) + ! This allows the parent to rewrite system calls + ! and args on the fly. mov.l @(OFF_R4,r15), r4 ! arg0 mov.l @(OFF_R5,r15), r5 mov.l @(OFF_R6,r15), r6 @@ -357,8 +357,15 @@ syscall_call: mov.l 3f, r8 ! Load the address of sys_call_table add r8, r3 mov.l @r3, r8 + mov.l @(OFF_R2,r15), r2 + mov.l @(OFF_R1,r15), r1 + mov.l @(OFF_R0,r15), r0 + mov.l r2, @-r15 + mov.l r1, @-r15 + mov.l r0, @-r15 jsr @r8 ! jump to specific syscall handler nop + add #12, r15 mov.l @(OFF_R0,r15), r12 ! save r0 mov.l r0, @(OFF_R0,r15) ! save the return value ! diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 6af6e7c..594cd37 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -148,11 +148,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p return err; } -asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, -unsigned long r6, unsigned long r7, -struct pt_regs __regs) +asmlinkage int sys_sigreturn(void) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + struct pt_regs *regs = current_pt_regs(); struct sigframe __user *frame = (struct sigframe __user *)regs->regs[15]; sigset_t set; int r0; @@ -180,11 +178,9 @@ badframe: return 0; } -asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +asmlinkage int sys_rt_sigreturn(void) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + struct pt_regs *regs = current_pt_regs(); struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15]; sigset_t set; int r0; diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c index
[PATCH v2 2/4] of: reimplement the matching method for __of_match_node()
In the current implementation of __of_match_node(), it will compare each given match entry against all the node's compatible strings with of_device_is_compatible(). To achieve multiple compatible strings per node with ordering from specific to generic, this requires given matches to be ordered from specific to generic. For most of the drivers this is not true and also an alphabetical ordering is more sane there. Therefore, we define a following priority order for the match, and then scan all the entries to find the best match. 1. specific compatible && type && name 2. specific compatible && type 3. specific compatible && name 4. specific compatible 5. general compatible && type && name 6. general compatible && type 7. general compatible && name 8. general compatible 9. type && name 10. type 11. name This is based on some pseudo-codes provided by Grant Likely. Signed-off-by: Kevin Hao [grant.likely: Changed multiplier to 4 which makes more sense] Signed-off-by: Grant Likely --- v2: Fix the bug such as we get the same score for the following two match entries: name2 { } struct of_device_id matches[] = { {.name = "name2", }, {.name = "name2", .type = "type1", }, {} }; drivers/of/base.c | 93 +++ 1 file changed, 74 insertions(+), 19 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index ba195fbce4c6..4085e2af0b7f 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -342,21 +342,28 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) } EXPORT_SYMBOL(of_get_cpu_node); -/** Checks if the given "compat" string matches one of the strings in - * the device's "compatible" property +/* + * Compare with the __of_device_is_compatible, this will return a score for the + * matching strings. The smaller value indicates the match for the more specific + * compatible string. */ -static int __of_device_is_compatible(const struct device_node *device, -const char *compat) +static int __of_device_is_compatible_score(const struct device_node *device, +const char *compat, int *pscore) { const char* cp; int cplen, l; + int score = 0; cp = __of_get_property(device, "compatible", &cplen); if (cp == NULL) return 0; while (cplen > 0) { - if (of_compat_cmp(cp, compat, strlen(compat)) == 0) + score++; + if (of_compat_cmp(cp, compat, strlen(compat)) == 0) { + if (pscore) + *pscore = score; return 1; + } l = strlen(cp) + 1; cp += l; cplen -= l; @@ -368,6 +375,15 @@ static int __of_device_is_compatible(const struct device_node *device, /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ +static int __of_device_is_compatible(const struct device_node *device, +const char *compat) +{ + return __of_device_is_compatible_score(device, compat, NULL); +} + +/** Checks if the given "compat" string matches one of the strings in + * the device's "compatible" property + */ int of_device_is_compatible(const struct device_node *device, const char *compat) { @@ -734,25 +750,52 @@ static const struct of_device_id *__of_match_node(const struct of_device_id *matches, const struct device_node *node) { + const struct of_device_id *best_match = NULL; + int best_score = 0; + if (!matches) return NULL; while (matches->name[0] || matches->type[0] || matches->compatible[0]) { - int match = 1; - if (matches->name[0]) - match &= node->name - && !strcmp(matches->name, node->name); - if (matches->type[0]) - match &= node->type - && !strcmp(matches->type, node->type); - if (matches->compatible[0]) - match &= __of_device_is_compatible(node, - matches->compatible); - if (match) - return matches; + int score = 0; + + /* +* Matching compatible is better than matching type and name, +* and the specific compatible is better than the general. +*/ + if (matches->compatible[0] && +__of_device_is_compatible_score(node, + matches->compatible, &score)) + score = INT_MAX - 4 * score; + + /* +
[PATCH v2 0/3] Don't let system calls clobber userspace registers
When invoking syscall handlers on sh32, the saved userspace registers are at the top of the stack. This seems to have been intentional, as it is an easy way to pass r0, r1, ... to the handler as parameters 5, 6, ... It causes problems, however, because the compiler is allowed to generate code for a function which clobbers that function's own parameters. For example, gcc generates the following code for clone: : mov.l 8c020714 ,r1 ! 8c020540 mov.l r7,@r15 mov r6,r7 jmp @r1 mov #0,r6 nop .word 0x0540 .word 0x8c02 The `mov.l r7,@r15` clobbers the saved value of r0 passed from userspace. For most system calls, this might not be a problem, because we'll be overwriting r0 with the return value anyway. But in the case of clone, copy_thread will need the original value of r0 if the CLONE_SETTLS flag was specified. The first patch in this series fixes this issue for system calls by pushing to the stack and extra copy of r0-r2 before invoking the handler. We discard this copy before restoring the userspace registers, so it is not a problem if they are clobbered. Exception handlers also receive the userspace register values in a similar manner, and may hit the same problem. The second patch removes the do_fpu_error handler, which looks susceptible to this problem and which, as far as I can tell, has not been used in some time. The third patch addresses other exception handlers. Changes since V1: - Update messages for [2/3] to quote the short log of the previous commit that left do_fpu_error unused. Bobby Bingham (3): sh: push extra copy of r0-r2 for syscall parameters sh: remove unused do_fpu_error sh: don't pass saved userspace state to exception handlers arch/sh/include/asm/syscalls_32.h | 12 +++- arch/sh/include/asm/traps_32.h| 16 arch/sh/kernel/entry-common.S | 15 +++ arch/sh/kernel/signal_32.c| 12 arch/sh/kernel/sys_sh32.c | 7 ++- arch/sh/kernel/traps_32.c | 23 +++ arch/sh/math-emu/math.c | 18 -- 7 files changed, 31 insertions(+), 72 deletions(-) -- 1.8.5.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 2/3] sh: remove unused do_fpu_error
This does not appear to have been used since commit 74d99a5e262229ee865f6f68528d10b82471ead6 (sh: SH-2A FPU support) in 2007. Signed-off-by: Bobby Bingham --- arch/sh/math-emu/math.c | 18 -- 1 file changed, 18 deletions(-) diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c index b876780..04aa55f 100644 --- a/arch/sh/math-emu/math.c +++ b/arch/sh/math-emu/math.c @@ -574,24 +574,6 @@ static int ieee_fpe_handler(struct pt_regs *regs) return 0; } -asmlinkage void do_fpu_error(unsigned long r4, unsigned long r5, -unsigned long r6, unsigned long r7, -struct pt_regs regs) -{ - struct task_struct *tsk = current; - siginfo_t info; - - if (ieee_fpe_handler (®s)) - return; - - regs.pc += 2; - info.si_signo = SIGFPE; - info.si_errno = 0; - info.si_code = FPE_FLTINV; - info.si_addr = (void __user *)regs.pc; - force_sig_info(SIGFPE, &info, tsk); -} - /** * fpu_init - Initialize FPU registers * @fpu: Pointer to software emulated FPU registers. -- 1.8.5.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 3/3] sh: don't pass saved userspace state to exception handlers
The compiler is permitted to generate code which overwrites the parameters to a function. If those parameters include the only saved copy we have of userspace's registers, we're in trouble. Signed-off-by: Bobby Bingham --- arch/sh/include/asm/traps_32.h | 16 arch/sh/kernel/traps_32.c | 23 +++ 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/arch/sh/include/asm/traps_32.h b/arch/sh/include/asm/traps_32.h index cfd55ff..17e129f 100644 --- a/arch/sh/include/asm/traps_32.h +++ b/arch/sh/include/asm/traps_32.h @@ -42,18 +42,10 @@ static inline void trigger_address_error(void) asmlinkage void do_address_error(struct pt_regs *regs, unsigned long writeaccess, unsigned long address); -asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); -asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); -asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); -asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); +asmlinkage void do_divide_error(unsigned long r4); +asmlinkage void do_reserved_inst(void); +asmlinkage void do_illegal_slot_inst(void); +asmlinkage void do_exception_error(void); #define BUILD_TRAP_HANDLER(name) \ asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5, \ diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 68e99f0..ff63934 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -594,9 +594,7 @@ int is_dsp_inst(struct pt_regs *regs) #endif /* CONFIG_SH_DSP */ #ifdef CONFIG_CPU_SH2A -asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +asmlinkage void do_divide_error(unsigned long r4) { siginfo_t info; @@ -613,11 +611,9 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, } #endif -asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +asmlinkage void do_reserved_inst(void) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + struct pt_regs *regs = current_pt_regs(); unsigned long error_code; struct task_struct *tsk = current; @@ -701,11 +697,9 @@ static int emulate_branch(unsigned short inst, struct pt_regs *regs) } #endif -asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +asmlinkage void do_illegal_slot_inst(void) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + struct pt_regs *regs = current_pt_regs(); unsigned long inst; struct task_struct *tsk = current; @@ -730,15 +724,12 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, die_if_no_fixup("illegal slot instruction", regs, inst); } -asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +asmlinkage void do_exception_error(void) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); long ex; ex = lookup_exception_vector(); - die_if_kernel("exception", regs, ex); + die_if_kernel("exception", current_pt_regs(), ex); } void per_cpu_trap_init(void) -- 1.8.5.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 0/3] usb: chipidea: msm: Clean and fix glue layer driver
Ivan, I'm having tremendous problems getting this driver to initialize. For some reason, I can't get the driver to actually transition the hardware into peripheral mode. At first I was getting a lot of probe deferrals, based on not finding the regulators early enough in the boot, and I thought it was an issue with the gadget drivers loading before the driver could complete its setup. However, I switched everything to loading via modules, and now have less probe deferrals, but I still can't get the driver to activate. I see zero interrupts. In particular the routine hw_device_state (which turns on interrupts in the controller) is never called, because I can't get msm_otg_start_peripheral to actually kick the hardware. I've sprinkled the code in drivers/usb/chipidea and drivers/usb/phy/phy-msm-usb.c liberally with printks and WARNs to help me see what's going on, but I'm having a hard time tracing it down. I'm pretty sure I've got the DTS correct, but my USB config might not match yours. (Would you mind sharing your config?). I tried configuring the qcom,otg-control for user controlled mode setting (via debugfs), and even with doing "echo "peripheral" >/sys/kernel/debug/msm_otg/mode, it just wouldn't start the hardware (call hw_device_state(...1)). Any ideas you can provide would be welcome (e.g. for things to try, look at, etc.) My kernel is based on an internal Sony 3.13-rc6 kernel with clock and regulator patches applied, as well as your phy-msm-usb.c patches from November and your chipidea patches from yesterday. Thanks, -- Tim In the printk dump below, UBTO=udc_bind_to_driver CIS=ci_udc_start MOSP=msm_otg_set_peripheral MOSW=msm_otg_sm_work [10] platform_init() [10] target_init() [10] Display Init: Start [10] display_init(),target_id=10. [30] Config MIPI_VIDEO_PANEL. [30] Turn on MIPI_VIDEO_PANEL. [50] Video lane tested successfully [50] Display Init: Done [70] partition misc doesn't exist [80] error in emmc_recovery_init [80] No 'misc' partition found [80] Error reading MISC partition [80] failed to get ffbm cookie[90] use_signed_kernel=1, is_unlocked=0, is_tampered=1. [90] Loading boot image (7829504): start [550] Loading boot image (7829504): done [550] Found Appeneded Flattened Device tree [550] cmdline: console=ttyMSM,115200,n8 androidboot.hardware=qcom user_debug=31 maxcpus=2 msm_rtb.filter=0x37 ehci-hcd.park=3 earl yprintk debug androidboot.emmc=true androidboot.serialno=40081a14 androidboot.baseband=apq [570] Updating device tree: start [570] Updating device tree: done [580] booting linux @ 0x8000, ramdisk @ 0x200 (4234892), tags/device tree @ 0x1e0 [580] Turn off MIPI_VIDEO_PANEL. [580] Continuous splash enabled, keeping panel alive. Uncompressing Linux... done, booting the kernel. [0.00] Booting Linux on physical CPU 0x0 [0.00] TRB: version 8 [0.00] Linux version 3.13.0-rc6-00147-g00bb56a-dirty (10102229@ussvlx8980) (gcc version 4.6.x-google 20120106 (prerelease) (GCC) ) #40 SMP PREEMPT Tue Feb 18 19:24:12 PST 2014 [0.00] CPU: ARMv7 Processor [512f06f0] revision 0 (ARMv7), cr=10c5387d [0.00] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache [0.00] Machine model: Qualcomm APQ8074 Dragonboard [0.00] bootconsole [earlycon0] enabled [0.00] Memory policy: Data cache writealloc [0.00] On node 0 totalpages: 524288 [0.00] free_area_init_node: node 0, pgdat c0908d80, node_mem_map c098 [0.00] Normal zone: 1520 pages used for memmap [0.00] Normal zone: 0 pages reserved [0.00] Normal zone: 194560 pages, LIFO batch:31 [0.00] HighMem zone: 2576 pages used for memmap [0.00] HighMem zone: 329728 pages, LIFO batch:31 [0.00] PERCPU: Embedded 8 pages/cpu @c1993000 s12224 r8192 d12352 u32768 [0.00] pcpu-alloc: s12224 r8192 d12352 u32768 alloc=8*4096 [0.00] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0.00] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 522768 [0.00] Kernel command line: console=ttyMSM,115200,n8 androidboot.hardware=qcom user_debug=31 maxcpus=2 msm_rtb.filter=0x37 ehci-hcd.park=3 earlyprintk debug androidboot.emmc=true androidboot.serialno=40081a14 androidboot.baseband=apq [0.00] PID hash table entries: 4096 (order: 2, 16384 bytes) [0.00] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) [0.00] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) [0.00] Memory: 2067932K/2097152K available (4734K kernel code, 262K rwdata, 1912K rodata, 287K init, 446K bss, 29220K rese rved, 1318912K highmem) [0.00] Virtual kernel memory layout: [0.00] vector : 0x - 0x1000 ( 4 kB) [0.00] fixmap : 0xfff0 - 0xfffe ( 896 kB) [0.00] vmalloc : 0xf000 - 0xff00 ( 240 MB) [0.00] lowmem : 0xc000 - 0xef80 ( 760 MB) [0.00]
Re: [PATCH] atm: libahci: replace obselete simple_strtoul() with kstrtouint()
I re-send this patch after fixing subject. Thanks. Daeseok Youn 2014-02-19 15:05 GMT+09:00 David Miller : > From: Daeseok Youn > Date: Wed, 19 Feb 2014 14:09:49 +0900 > >> From 18bd7236f36a248a0871f810cec3c1e98f098a91 Mon Sep 17 00:00:00 2001 >> From: Daeseok Youn >> Date: Wed, 19 Feb 2014 13:44:24 +0900 >> Subject: [PATCH] atm: libahci: replace obselete simple_strtoul() with >> kstrtouint() >> >> Signed-off-by: Daeseok Youn > > Please fix your Subject line, you meant "ata: " not "atm: " -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ata: libahci: replace obselete simple_strtoul() with kstrtouint()
>From a6ff4eec0b80ff6596a278623a02e3ed462c49ed Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 19 Feb 2014 13:44:24 +0900 Subject: [PATCH] ata: libahci: replace obselete simple_strtoul() with kstrtouint() Signed-off-by: Daeseok Youn --- drivers/ata/libahci.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 36605ab..417946b 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1032,12 +1032,13 @@ static ssize_t ahci_led_show(struct ata_port *ap, char *buf) static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, size_t size) { - int state; + unsigned int state; int pmp; struct ahci_port_priv *pp = ap->private_data; struct ahci_em_priv *emp; - state = simple_strtoul(buf, NULL, 0); + if (kstrtouint(buf, 0, &state) < 0) + return -EINVAL; /* get the slot number from the message */ pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; -- 1.7.9.5 --- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
How could we get rid of saved_max_pfn for calgary iommu?
Hi, All arch/x86/kernel/pci-calgary.c is the only user of saved_max_pfn today: int __init detect_calgary(void) { [..] specified_table_size = determine_tce_table_size((is_kdump_kernel() ? saved_max_pfn : max_pfn) * PAGE_SIZE); [..] } saved_max_pfn is the real mem size and is calculated by 1st kernel E820 memmap which is passed in by 2nd kernel's boot_params (done by kexec): saved_max_pfn = e820_end_of_ram_pfn(); After saved_max_pfn has been set, memmap=exactmap will reset the E820 provided by boot_params and use the user defined E820 instead. Now we want to get rid of memmap=exactmap and directly pass the E820 memmap by boot_params for some reason (eg. exactmap may exceed the cmdline size and also isn't compatible with kaslr). However saved_max_pfn becomes the obstacle for obsoleting exactmap. Because it needs two conditions: first kernel's E820 map and memmap=exactmap cmdline. So I'm wondering if it's possible to get rid of saved_max_pfn totally in calgary code. Or we can get saved_max_pfn using a different way, for example calculated in 1st kernel and passed in to 2nd kernel by cmdline. Thanks WANG Chao -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCHv5 0/4] add compressing abstraction and multi stream support
On Tue, Feb 18, 2014 at 10:38:18PM +0300, Sergey Senozhatsky wrote: > On (02/18/14 15:04), Minchan Kim wrote: > [..] > > 1.8.5.3 > > > > As you can see, your patch made zram too much regressed when it > > used one stream buffer. The reason I guessed is overhead of > > scheduling by sleep/wakeup when others couldn't find a idle stream > > so I had an experiment with below simple patch to restore old behavior > > so it works well again. The reason old behaivor was really good is > > it uses mutex with spin_on_owner so that it could avoid frequent > > sleep/wakeup. > > > > A solution I could think is that we could grow up the number of > > buffer dynamically up to max_buffers(ex, 2 * number of CPU) so we > > could grab a idle stream easily for each CPU while we could release > > buffers by shrinker when the memory pressure is severe. > > Of course, we should keep one buffer to work. > > > > Another solution I can imagaine is to define CONFIG_ZRAM_MULTI_STREAM > > and CONFIG_ZRAM_SINGLE_STREAM(ie, default) so we couldn't break good > > performance for old cases and new users who want write parallel > > could use ZRAM_MULTI which should be several streams at a default > > rather than a stream. And we could ehhacne it further by dynamic control > > as I mentioned. > > > > Thoughts? > > > > like the following one (this patch limits the number of streams to > num_online_cpus(). I really don't mind to limit zstrm to > N * num_online_cpus() where N could be 2) > > iozone -t 3 -R -r 16K -s 60M -I +Z > > write test: > (old core i5 laptop, 2 cpus + 2 HyperThreading) > >basemulti buffer > > " Initial write " 574938.14 716623.64 > "Rewrite " 573541.22 1499074.62 > " Random write " 587016.14 1393996.66 > " Pwrite " 595616.45 711028.70 > " Fwrite " 1482843.62 1493398.12 > I guess you tested it for zram-block, not zram-swap. If we use it as zram-swap and happens parallel swapout, write performance would be dropped due to frequent sleep/wakeup. > > zcomp_strm_get() and zcomp_strm_put() were updated. > zcomp keeps the number allocated and still active (not freed) > streams (atomic_t). zcomp performs zstrm free() only if > current number of streams exceeds the number of online > cpus (cpu went offline). > > > not a properly `aligned' patch, just to demonstrate the idea. > > thoughts? > > thanks. > > --- > > >From 0e16f26480933d22339675ca938049dfb21557e2 Mon Sep 17 00:00:00 2001 > From: Sergey Senozhatsky > Date: Tue, 11 Feb 2014 00:28:46 +0300 > Subject: [PATCH] zram: multi stream compressing backend abstraction > > Signed-off-by: Sergey Senozhatsky > --- > drivers/block/zram/zcomp.c | 174 > + > drivers/block/zram/zcomp.h | 58 ++ > drivers/block/zram/zcomp_lzo.c | 48 > 3 files changed, 280 insertions(+) > create mode 100644 drivers/block/zram/zcomp.c > create mode 100644 drivers/block/zram/zcomp.h > create mode 100644 drivers/block/zram/zcomp_lzo.c > > diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c > new file mode 100644 > index 000..6bf49fc > --- /dev/null > +++ b/drivers/block/zram/zcomp.c > @@ -0,0 +1,174 @@ > +/* > + * Copyright (C) 2014 Sergey Senozhatsky. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version > + * 2 of the License, or (at your option) any later version. > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +#include "zcomp.h" > + > +extern struct zcomp_backend zcomp_lzo; > + > +static struct zcomp_backend *find_backend(const char *compress) > +{ > + if (strncmp(compress, "lzo", 3) == 0) > + return &zcomp_lzo; > + return NULL; > +} > + > +static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm) > +{ > + if (zstrm->private) > + comp->backend->destroy(zstrm->private); > + free_pages((unsigned long)zstrm->buffer, 1); > + kfree(zstrm); > +} > + > +/* > + * allocate new zcomp_strm structure with ->private initialized by > + * backend, return NULL on error > + */ > +static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp) > +{ > + struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL); > + if (!zstrm) > + return NULL; > + > + zstrm->private = comp->backend->create(); > + /* > + * allocate 2 pages. 1 for compressed data, plus 1 extra for the > + * case when compressed size is larger than the original one > + */ > + zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1); > + if (!zstrm->private || !zstrm->buffer) { > + zcomp_strm_free(comp, zstrm); > + zstrm = NULL; > + } > + return zstrm; > +} > + > +/* > + * get
Re: [PATCHv5 0/4] add compressing abstraction and multi stream support
Hello Sergey, On Tue, Feb 18, 2014 at 12:20:17PM +0300, Sergey Senozhatsky wrote: > Hello, > > On (02/18/14 15:04), Minchan Kim wrote: > > Hello Sergey, > > > > On Thu, Feb 13, 2014 at 08:43:18PM +0300, Sergey Senozhatsky wrote: > > > This patchset introduces zcomp compression backend abstraction > > > adding ability to support compression algorithms other than LZO; > > > support for multi compression streams, making parallel compressions > > > possible. > > > > > > Diff from v4 (reviewed by Minchan Kim): > > > -- renamed zcomp buffer_lock; removed src len and dst len from > > >compress() and decompress(); not using term `buffer' and > > >`workmem' in code and documentation; define compress() and > > >decompress() functions for LZO backend; not using goto's; > > >do not put idle zcomp_strm to idle list tail. > > > > > > Diff from v3: > > > -- renamed compression backend and working memory structs as requested > > >by Minchan Kim; fixed several issues noted by Minchan Kim. > > > > > > Sergey Senozhatsky (4): > > > zram: introduce compressing backend abstraction > > > zram: use zcomp compressing backends > > > zram: zcomp support multi compressing streams > > > zram: document max_comp_streams > > > > > > Documentation/ABI/testing/sysfs-block-zram | 9 +- > > > Documentation/blockdev/zram.txt| 20 +++- > > > drivers/block/zram/Makefile| 2 +- > > > drivers/block/zram/zcomp.c | 155 > > > + > > > drivers/block/zram/zcomp.h | 56 +++ > > > drivers/block/zram/zcomp_lzo.c | 48 + > > > drivers/block/zram/zram_drv.c | 102 --- > > > drivers/block/zram/zram_drv.h | 10 +- > > > 8 files changed, 355 insertions(+), 47 deletions(-) > > > create mode 100644 drivers/block/zram/zcomp.c > > > create mode 100644 drivers/block/zram/zcomp.h > > > create mode 100644 drivers/block/zram/zcomp_lzo.c > > > > I reviewed patchset and implement looked good to me but > > I found severe regression in my test which was one stream. > > > > Base is current upstream and zcomp-multi is yours. > > At last, zcom-single is where I tweaked to see schedule overhead > > cause by event. > > > >Base zcomp-multi zcomp-single > > > > ==Initial write ==Initial write ==Initial write > > records: 5 records: 5 records: 5 > > avg: 1642424.35avg: 699610.40 avg: > > 1655583.71 > > wow... spinlock vs mutex 3 times slower? that's ugly. > can you please provide iozone arg list? iozone -t -T -l 12 -u 12 -r 16K -s 60M -I +Z -V 0 > > > std: 39890.95(2.43%) std: 232014.19(33.16%) std: > > 52293.96(3.16%) > > max: 1690170.94max: 1163473.45 max: > > 1697164.75 > > min: 1568669.52min: 573429.88 min: > > 1553410.23 > > ==Rewrite ==Rewrite ==Rewrite > > records: 5 records: 5 records: 5 > > avg: 1611775.39avg: 501406.64 avg: > > 1684419.11 > > std: 17144.58(1.06%) std: 15354.41(3.06%)std: > > 18367.42(1.09%) > > max: 1641800.95max: 531356.78 max: > > 1706445.84 > > min: 1593515.27min: 488817.78 min: > > 1655335.73 > > ==Read ==Read==Read > > records: 5 records: 5 records: 5 > > avg: 2418916.31avg: 2385573.68 avg: > > 2316542.26 > > std: 55324.98(2.29%) std: 64475.37(2.70%)std: > > 50621.10(2.19%) > > max: 2517417.72max: 2444138.89 max: > > 2383321.09 > > min: 2364690.92min: 2263763.77 min: > > 2233198.12 > > ==Re-read ==Re-read ==Re-read > > records: 5 records: 5 records: 5 > > avg: 2351292.92avg: 2333131.90 avg: > > 2336306.89 > > std: 73358.82(3.12%) std: 34726.09(1.49%)std: > > 74001.47(3.17%) > > max: 2444053.92max: 2396357.19 max: > > 2432697.06 > > min: 2255477.41min: 2299239.74 min: > > 2231400.94 > > ==Reverse Read ==Reverse Read ==Reverse Read > > records: 5 records: 5 records: 5 > > avg: 2383917.40avg: 2267700.38 avg: > > 2328689.00 > > std: 51389.78(2.16%) std: 57018.67(2.51%)std: > > 44955.21(1.93%) > > max: 2435560.11max: 2346465.31 max: > > 2375047.77 > > min: 2290726.91min: 2188208.84
[Patch Part2 V2 02/17] iommu/vt-d: avoid caching stale domain_device_info and fix memory leak
Function device_notifier() in intel-iommu.c fails to remove device_domain_info data structures for PCI devices if they are associated with si_domain because iommu_no_mapping() returns true for those PCI devices. This will cause memory leak and caching of stale information in domain->devices list. So fix the issue by not calling iommu_no_mapping() and skipping check of iommu_pass_through. Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 52be755..f75d3ae 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3600,14 +3600,14 @@ static int device_notifier(struct notifier_block *nb, struct pci_dev *pdev = to_pci_dev(dev); struct dmar_domain *domain; - if (iommu_no_mapping(dev)) + if (iommu_dummy(pdev)) return 0; domain = find_domain(pdev); if (!domain) return 0; - if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) { + if (action == BUS_NOTIFY_UNBOUND_DRIVER) { domain_remove_one_dev_info(domain, pdev); if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 12/28] Remove GENERIC_TIME
On Sun, Feb 9, 2014 at 12:02 PM, Richard Weinberger wrote: > Am 09.02.2014 19:57, schrieb Alexander Shiyan: >>> The symbol is an orphan, get rid of it. >>> >>> Signed-off-by: Richard Weinberger >>> --- >>> arch/arm/mach-bcm/Kconfig | 1 - >>> 1 file changed, 1 deletion(-) >>> >>> diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig >>> index b1aa6a9..8dd5fbf 100644 >>> --- a/arch/arm/mach-bcm/Kconfig >>> +++ b/arch/arm/mach-bcm/Kconfig >>> @@ -19,7 +19,6 @@ config ARCH_BCM_MOBILE >>> select CPU_V7 >>> select CLKSRC_OF >>> select GENERIC_CLOCKEVENTS >>> -select GENERIC_TIME >>> select GPIO_BCM_KONA >>> select SPARSE_IRQ >>> select TICK_ONESHOT >>> -- >>> 1.8.4.2 >> Applied to armsoc/for-3.15/soc Also added signed-off-by for Alexander Shyian and Paul Bolle. Thanks, csd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v4 1/8] clk: sunxi: Add Allwinner A20/A31 GMAC clock unit
Quoting Chen-Yu Tsai (2014-02-10 02:35:47) > The Allwinner A20/A31 clock module controls the transmit clock source > and interface type of the GMAC ethernet controller. Model this as > a single clock for GMAC drivers to use. > > Signed-off-by: Chen-Yu Tsai Looks good to me. Regards, Mike > --- > Documentation/devicetree/bindings/clock/sunxi.txt | 30 +++ > drivers/clk/sunxi/clk-sunxi.c | 97 > +++ > 2 files changed, 127 insertions(+) > > diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt > b/Documentation/devicetree/bindings/clock/sunxi.txt > index 0cf679b..28421d2 100644 > --- a/Documentation/devicetree/bindings/clock/sunxi.txt > +++ b/Documentation/devicetree/bindings/clock/sunxi.txt > @@ -37,6 +37,7 @@ Required properties: > "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 > "allwinner,sun4i-mod0-clk" - for the module 0 family of clocks > "allwinner,sun7i-a20-out-clk" - for the external output clocks > + "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31 > > Required properties for all clocks: > - reg : shall be the control register address for the clock. > @@ -50,6 +51,9 @@ Required properties for all clocks: > If the clock module only has one output, the name shall be the > module name. > > +For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate > +dummy clocks at 25 MHz and 125 MHz, respectively. See example. > + > Clock consumers should specify the desired clocks they use with a > "clocks" phandle cell. Consumers that are using a gated clock should > provide an additional ID in their clock property. This ID is the > @@ -96,3 +100,29 @@ mmc0_clk: clk@01c20088 { > clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; > clock-output-names = "mmc0"; > }; > + > +mii_phy_tx_clk: clk@2 { > + #clock-cells = <0>; > + compatible = "fixed-clock"; > + clock-frequency = <2500>; > + clock-output-names = "mii_phy_tx"; > +}; > + > +gmac_int_tx_clk: clk@3 { > + #clock-cells = <0>; > + compatible = "fixed-clock"; > + clock-frequency = <12500>; > + clock-output-names = "gmac_int_tx"; > +}; > + > +gmac_clk: clk@01c20164 { > + #clock-cells = <0>; > + compatible = "allwinner,sun7i-a20-gmac-clk"; > + reg = <0x01c20164 0x4>; > + /* > +* The first clock must be fixed at 25MHz; > +* the second clock must be fixed at 125MHz > +*/ > + clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>; > + clock-output-names = "gmac"; > +}; > diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c > index 736fb60..da1d5cc 100644 > --- a/drivers/clk/sunxi/clk-sunxi.c > +++ b/drivers/clk/sunxi/clk-sunxi.c > @@ -379,6 +379,103 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 > parent_rate, > > > /** > + * sun7i_a20_gmac_clk_setup - Setup function for A20/A31 GMAC clock module > + * > + * This clock looks something like this > + * > + * MII TX clock from PHY >-|____|> to GMAC core > + * GMAC Int. RGMII TX clk >|___\__/__gate---|> to PHY > + * Ext. 125MHz RGMII TX clk >--|__divider__/| > + * || > + * > + * The external 125 MHz reference is optional, i.e. GMAC can use its > + * internal TX clock just fine. The A31 GMAC clock module does not have > + * the divider controls for the external reference. > + * > + * To keep it simple, let the GMAC use either the MII TX clock for MII mode, > + * and its internal TX clock for GMII and RGMII modes. The GMAC driver should > + * select the appropriate source and gate/ungate the output to the PHY. > + * > + * Only the GMAC should use this clock. Altering the clock so that it doesn't > + * match the GMAC's operation parameters will result in the GMAC not being > + * able to send traffic out. The GMAC driver should set the clock rate and > + * enable/disable this clock to configure the required state. The clock > + * driver then responds by auto-reparenting the clock. > + */ > + > +#define SUN7I_A20_GMAC_GPIT2 > +#define SUN7I_A20_GMAC_MASK0x3 > +#define SUN7I_A20_GMAC_PARENTS 2 > + > +static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) > +{ > + struct clk *clk; > + struct clk_mux *mux; > + struct clk_gate *gate; > + const char *clk_name = node->name; > + const char *parents[SUN7I_A20_GMAC_PARENTS]; > + void *reg; > + int i = 0; > + > + if (of_property_read_string(node, "clock-output-names", &clk_name)) > + return; > + > + /* allocate mux and gate clock structs */ > + mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); > + if (!mux) > + return; > + > + gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); > +
[Patch Part2 V2 01/17] iommu/vt-d: avoid double free of g_iommus on error recovery path
Array 'g_iommus' may be freed twice on error recovery path in function init_dmars() and free_dmar_iommu(), thus cause random system crash as below. [6.774301] IOMMU: dmar init failed [6.778310] PCI-DMA: Using software bounce buffering for IO (SWIOTLB) [6.785615] software IO TLB [mem 0x76bcf000-0x7abcf000] (64MB) mapped at [880076bcf000-88007abcefff] [6.796887] general protection fault: [#1] SMP DEBUG_PAGEALLOC [6.804173] Modules linked in: [6.807731] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.14.0-rc1+ #108 [6.815122] Hardware name: Intel Corporation BRICKLAND/BRICKLAND, BIOS BRIVTIN1.86B.0047.R00.1402050741 02/05/2014 [6.836000] task: 880455a8 ti: 880455a88000 task.ti: 880455a88000 [6.844487] RIP: 0010:[] [] memcpy+0x6/0x110 [6.853039] RSP: :880455a89cc8 EFLAGS: 00010293 [6.859064] RAX: 006568636163 RBX: 00656863616a RCX: 0005 [6.867134] RDX: 0005 RSI: 81cdc439 RDI: 006568636163 [6.875205] RBP: 880455a89d30 R08: 0001bc3b R09: [6.883275] R10: R11: 81cdc43e R12: 880455a89da8 [6.891338] R13: 006568636163 R14: 0005 R15: 81cdc439 [6.899408] FS: () GS:88045b80() knlGS: [6.908575] CS: 0010 DS: ES: CR0: 80050033 [6.915088] CR2: 88047e1ff000 CR3: 01e0e000 CR4: 001407f0 [6.923160] Stack: [6.925487] 8143c904 88045b407e00 006568636163 006568636163 [6.934113] 8120a1a9 81cdc43e 0007 [6.942747] 880455a89da8 006568636163 0007 81cdc439 [6.951382] Call Trace: [6.954197] [] ? vsnprintf+0x124/0x6f0 [6.960323] [] ? __kmalloc_track_caller+0x169/0x360 [6.967716] [] kvasprintf+0x6b/0x80 [6.973552] [] kobject_set_name_vargs+0x21/0x70 [6.980552] [] kobject_init_and_add+0x4d/0x90 [6.987364] [] ? __kmalloc+0x169/0x370 [6.993492] [] ? cache_add_dev+0x17c/0x4f0 [7.05] [] cache_add_dev+0x3ba/0x4f0 [7.006327] [] ? i8237A_init_ops+0x14/0x14 [7.012842] [] cache_sysfs_init+0x2e/0x61 [7.019260] [] do_one_initcall+0xf2/0x220 [7.025679] [] ? parse_args+0x2c9/0x450 [7.031903] [] kernel_init_freeable+0x1c9/0x25b [7.038904] [] ? do_early_param+0x8a/0x8a [7.045322] [] ? rest_init+0x150/0x150 [7.051447] [] kernel_init+0xe/0x100 [7.057380] [] ret_from_fork+0x7c/0xb0 [7.063503] [] ? rest_init+0x150/0x150 [7.069628] Code: 89 e5 53 48 89 fb 75 16 80 7f 3c 00 75 05 e8 d2 f9 ff ff 48 8b 43 58 48 2b 43 50 88 43 4e 5b 5d c3 90 90 90 90 48 89 f8 48 89 d1 a4 c3 03 83 e2 07 f3 48 a5 89 d1 f3 a4 c3 20 4c 8b 06 4c 8b [7.094960] RIP [] memcpy+0x6/0x110 [7.100856] RSP [7.104864] ---[ end trace b5d3fdc6c6c28083 ]--- [7.110142] Kernel panic - not syncing: Attempted to kill init! exitcode=0x000b [7.110142] [7.120540] Kernel Offset: 0x0 from 0x8100 (relocation range: 0x8000-0x9fff) Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c | 26 ++ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index a22c86c..52be755 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1298,15 +1298,6 @@ static void free_dmar_iommu(struct intel_iommu *iommu) g_iommus[iommu->seq_id] = NULL; - /* if all iommus are freed, free g_iommus */ - for (i = 0; i < g_num_of_iommus; i++) { - if (g_iommus[i]) - break; - } - - if (i == g_num_of_iommus) - kfree(g_iommus); - /* free context mapping */ free_context_table(iommu); } @@ -2461,7 +2452,7 @@ static int __init init_dmars(void) sizeof(struct deferred_flush_tables), GFP_KERNEL); if (!deferred_flush) { ret = -ENOMEM; - goto error; + goto free_g_iommus; } for_each_active_iommu(iommu, drhd) { @@ -2469,7 +2460,7 @@ static int __init init_dmars(void) ret = iommu_init_domains(iommu); if (ret) - goto error; + goto free_iommu; /* * TBD: @@ -2479,7 +2470,7 @@ static int __init init_dmars(void) ret = iommu_alloc_root_entry(iommu); if (ret) { printk(KERN_ERR "IOMMU: allocate root entry failed\n"); - goto error; + goto free_iommu; } if (!ecap_pass_through(iommu->ecap)) hw_pass_through = 0; @@ -2548,7 +2539,7 @@ static int __init init_dmars(void) ret = iom
[Patch Part2 V2 04/17] iommu/vt-d: factor out dmar_alloc_dev_scope() for later reuse
Factor out function dmar_alloc_dev_scope() from dmar_parse_dev_scope() for later reuse. Signed-off-by: Jiang Liu --- drivers/iommu/dmar.c | 28 include/linux/dmar.h |1 + 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 1581565..58dde75 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -117,13 +117,9 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, return 0; } -int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, - struct pci_dev ***devices, u16 segment) +void *dmar_alloc_dev_scope(void *start, void *end, int *cnt) { struct acpi_dmar_device_scope *scope; - void * tmp = start; - int index; - int ret; *cnt = 0; while (start < end) { @@ -138,15 +134,24 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, start += scope->length; } if (*cnt == 0) - return 0; + return NULL; + + return kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL); +} + +int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, + struct pci_dev ***devices, u16 segment) +{ + struct acpi_dmar_device_scope *scope; + int index, ret; - *devices = kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL); - if (!*devices) + *devices = dmar_alloc_dev_scope(start, end, cnt); + if (*cnt == 0) + return 0; + else if (!*devices) return -ENOMEM; - start = tmp; - index = 0; - while (start < end) { + for (index = 0; start < end; start += scope->length) { scope = start; if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT || scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) { @@ -158,7 +163,6 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, } index ++; } - start += scope->length; } return 0; diff --git a/include/linux/dmar.h b/include/linux/dmar.h index eccb0c0..1b08ce8 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -69,6 +69,7 @@ extern int dmar_table_init(void); extern int dmar_dev_scope_init(void); extern int dmar_parse_dev_scope(void *start, void *end, int *cnt, struct pci_dev ***devices, u16 segment); +extern void *dmar_alloc_dev_scope(void *start, void *end, int *cnt); extern void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt); /* Intel IOMMU detection */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch Part2 V2 03/17] iommu/vt-d: avoid caching stale domain_device_info when hot-removing PCI device
Function device_notifier() in intel-iommu.c only remove domain_device_info data structure associated with a PCI device when handling PCI device driver unbinding events. If a PCI device has never been bound to a PCI device driver, there won't be BUS_NOTIFY_UNBOUND_DRIVER event when hot-removing the PCI device. So associated domain_device_info data structure may get lost. On the other hand, if iommu_pass_through is enabled, function iommu_prepare_static_indentify_mapping() will create domain_device_info data structure for each PCIe to PCIe bridge and PCIe endpoint, no matter whether there are drivers associated with those PCIe devices or not. So those domain_device_info data structures will get lost when hot-removing the assocated PCIe devices if they have never bound to any PCI device driver. To be even worse, it's not only an memory leak issue, but also an caching of stale information bug because the memory are kept in device_domain_list and domain->devices lists. Fix the bug by trying to remove domain_device_info data structure when handling BUS_NOTIFY_DEL_DEVICE event. Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index f75d3ae..5a411e8 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3603,18 +3603,19 @@ static int device_notifier(struct notifier_block *nb, if (iommu_dummy(pdev)) return 0; + if (action != BUS_NOTIFY_UNBOUND_DRIVER && + action != BUS_NOTIFY_DEL_DEVICE) + return 0; + domain = find_domain(pdev); if (!domain) return 0; - if (action == BUS_NOTIFY_UNBOUND_DRIVER) { - domain_remove_one_dev_info(domain, pdev); - - if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && - !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) && - list_empty(&domain->devices)) - domain_exit(domain); - } + domain_remove_one_dev_info(domain, pdev); + if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && + !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) && + list_empty(&domain->devices)) + domain_exit(domain); return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch Part2 V2 08/17] iommu/vt-d: reduce duplicated code to handle virtual machine domains
Reduce duplicated code to handle virtual machine domains, there's no functionality changes. It also improves code readability. Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c | 177 +++ 1 file changed, 45 insertions(+), 132 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 503cc73..6724772 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -425,9 +425,12 @@ static LIST_HEAD(unmaps_to_do); static int timer_on; static long list_size; +static void domain_exit(struct dmar_domain *domain); static void domain_remove_dev_info(struct dmar_domain *domain); static void domain_remove_one_dev_info(struct dmar_domain *domain, struct pci_dev *pdev); +static void iommu_detach_dependent_devices(struct intel_iommu *iommu, + struct pci_dev *pdev); #ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON int dmar_disabled = 0; @@ -1286,10 +1289,6 @@ static int iommu_init_domains(struct intel_iommu *iommu) return 0; } - -static void domain_exit(struct dmar_domain *domain); -static void vm_domain_exit(struct dmar_domain *domain); - static void free_dmar_iommu(struct intel_iommu *iommu) { struct dmar_domain *domain; @@ -1304,12 +1303,8 @@ static void free_dmar_iommu(struct intel_iommu *iommu) spin_lock_irqsave(&domain->iommu_lock, flags); count = --domain->iommu_count; spin_unlock_irqrestore(&domain->iommu_lock, flags); - if (count == 0) { - if (domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) - vm_domain_exit(domain); - else - domain_exit(domain); - } + if (count == 0) + domain_exit(domain); } } @@ -1327,8 +1322,10 @@ static void free_dmar_iommu(struct intel_iommu *iommu) free_context_table(iommu); } -static struct dmar_domain *alloc_domain(void) +static struct dmar_domain *alloc_domain(bool vm) { + /* domain id for virtual machine, it won't be set in context */ + static atomic_t vm_domid = ATOMIC_INIT(0); struct dmar_domain *domain; domain = alloc_domain_mem(); @@ -1336,8 +1333,15 @@ static struct dmar_domain *alloc_domain(void) return NULL; domain->nid = -1; + domain->iommu_count = 0; memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp)); domain->flags = 0; + spin_lock_init(&domain->iommu_lock); + INIT_LIST_HEAD(&domain->devices); + if (vm) { + domain->id = atomic_inc_return(&vm_domid); + domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE; + } return domain; } @@ -1374,22 +1378,16 @@ static void iommu_detach_domain(struct dmar_domain *domain, { unsigned long flags; int num, ndomains; - int found = 0; spin_lock_irqsave(&iommu->lock, flags); ndomains = cap_ndoms(iommu->cap); for_each_set_bit(num, iommu->domain_ids, ndomains) { if (iommu->domains[num] == domain) { - found = 1; + clear_bit(num, iommu->domain_ids); + iommu->domains[num] = NULL; break; } } - - if (found) { - clear_bit(num, iommu->domain_ids); - clear_bit(iommu->seq_id, domain->iommu_bmp); - iommu->domains[num] = NULL; - } spin_unlock_irqrestore(&iommu->lock, flags); } @@ -1461,8 +1459,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width) unsigned long sagaw; init_iova_domain(&domain->iovad, DMA_32BIT_PFN); - spin_lock_init(&domain->iommu_lock); - domain_reserve_special_ranges(domain); /* calculate AGAW */ @@ -1481,7 +1477,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width) return -ENODEV; } domain->agaw = agaw; - INIT_LIST_HEAD(&domain->devices); if (ecap_coherent(iommu->ecap)) domain->iommu_coherency = 1; @@ -1518,7 +1513,9 @@ static void domain_exit(struct dmar_domain *domain) if (!intel_iommu_strict) flush_unmaps_timeout(0); + /* remove associated devices */ domain_remove_dev_info(domain); + /* destroy iovas */ put_iova_domain(&domain->iovad); @@ -1528,8 +1525,10 @@ static void domain_exit(struct dmar_domain *domain) /* free page tables */ dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); + /* clear attached or cached domains */ for_each_active_iommu(iommu, drhd) - if (test_bit(i
[Patch Part2 V2 06/17] iommu/vt-d: simplify function get_domain_for_dev()
Function get_domain_for_dev() is a little complex, simplify it by factoring out dmar_search_domain_by_dev_info() and dmar_insert_dev_info(). Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c | 142 --- 1 file changed, 66 insertions(+), 76 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index fffe3d1..67b114e 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1957,18 +1957,71 @@ find_domain(struct pci_dev *pdev) return NULL; } +static inline struct dmar_domain * +dmar_search_domain_by_dev_info(int segment, int bus, int devfn) +{ + struct device_domain_info *info; + + list_for_each_entry(info, &device_domain_list, global) + if (info->segment == segment && info->bus == bus && + info->devfn == devfn) + return info->domain; + + return NULL; +} + +static int dmar_insert_dev_info(int segment, int bus, int devfn, + struct pci_dev *dev, struct dmar_domain **domp) +{ + struct dmar_domain *found, *domain = *domp; + struct device_domain_info *info; + unsigned long flags; + + info = alloc_devinfo_mem(); + if (!info) + return -ENOMEM; + + info->segment = segment; + info->bus = bus; + info->devfn = devfn; + info->dev = dev; + info->domain = domain; + if (!dev) + domain->flags |= DOMAIN_FLAG_P2P_MULTIPLE_DEVICES; + + spin_lock_irqsave(&device_domain_lock, flags); + if (dev) + found = find_domain(dev); + else + found = dmar_search_domain_by_dev_info(segment, bus, devfn); + if (found) { + spin_unlock_irqrestore(&device_domain_lock, flags); + free_devinfo_mem(info); + if (found != domain) { + domain_exit(domain); + *domp = found; + } + } else { + list_add(&info->link, &domain->devices); + list_add(&info->global, &device_domain_list); + if (dev) + dev->dev.archdata.iommu = info; + spin_unlock_irqrestore(&device_domain_lock, flags); + } + + return 0; +} + /* domain is initialized */ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) { - struct dmar_domain *domain, *found = NULL; + struct dmar_domain *domain; struct intel_iommu *iommu; struct dmar_drhd_unit *drhd; - struct device_domain_info *info, *tmp; struct pci_dev *dev_tmp; unsigned long flags; int bus = 0, devfn = 0; int segment; - int ret; domain = find_domain(pdev); if (domain) @@ -1986,41 +2039,29 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) devfn = dev_tmp->devfn; } spin_lock_irqsave(&device_domain_lock, flags); - list_for_each_entry(info, &device_domain_list, global) { - if (info->segment == segment && - info->bus == bus && info->devfn == devfn) { - found = info->domain; - break; - } - } + domain = dmar_search_domain_by_dev_info(segment, bus, devfn); spin_unlock_irqrestore(&device_domain_lock, flags); /* pcie-pci bridge already has a domain, uses it */ - if (found) { - domain = found; + if (domain) goto found_domain; - } } - domain = alloc_domain(); - if (!domain) - goto error; - - /* Allocate new domain for the device */ drhd = dmar_find_matched_drhd_unit(pdev); if (!drhd) { printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", pci_name(pdev)); - free_domain_mem(domain); return NULL; } iommu = drhd->iommu; - ret = iommu_attach_domain(domain, iommu); - if (ret) { + /* Allocate and intialize new domain for the device */ + domain = alloc_domain(); + if (!domain) + goto error; + if (iommu_attach_domain(domain, iommu)) { free_domain_mem(domain); goto error; } - if (domain_init(domain, gaw)) { domain_exit(domain); goto error; @@ -2028,67 +2069,16 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) /* register pcie-to-pci device */ if (dev_tmp) { - info = alloc_devinfo_mem(); - if (!info) { + if (dmar_insert_dev_info(segment, bus, devfn, NULL, &domain)) {
[Patch Part2 V2 09/17] iommu/vt-d: fix incorrect iommu_count for si_domain
The iommu_count field in si_domain(static identity domain) is initialized to zero and never increases. It will underflow when tearing down iommu unit in function free_dmar_iommu() and leak memory. So refine code to correctly manage si_domain->iommu_count. Warning message caused by si_domain memory leak: [ 14.609681] IOMMU: Setting RMRR: [ 14.613496] Ignoring identity map for HW passthrough device :00:1a.0 [0xbdcfd000 - 0xbdd1dfff] [ 14.623809] Ignoring identity map for HW passthrough device :00:1d.0 [0xbdcfd000 - 0xbdd1dfff] [ 14.634162] IOMMU: Prepare 0-16MiB unity mapping for LPC [ 14.640329] Ignoring identity map for HW passthrough device :00:1f.0 [0x0 - 0xff] [ 14.673360] IOMMU: dmar init failed [ 14.678157] kmem_cache_destroy iommu_devinfo: Slab cache still has objects [ 14.686076] CPU: 12 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc1-gerry+ #59 [ 14.694176] Hardware name: Intel Corporation LH Pass ../SVRBD-ROW_T, BIOS SE5C600.86B.99.99.x059.091020121352 09/10/2012 [ 14.707412] 88042dd33db0 8156223d 880c2cc37c00 [ 14.716407] 88042dd33dc8 811790b1 880c2d3533b8 88042dd33e00 [ 14.725468] 81dc7a6a 81b1e8e0 81f84058 81d8a711 [ 14.734464] Call Trace: [ 14.737453] [] dump_stack+0x4d/0x66 [ 14.743430] [] kmem_cache_destroy+0xf1/0x100 [ 14.750279] [] intel_iommu_init+0x122/0x56a [ 14.757035] [] ? iommu_setup+0x27d/0x27d [ 14.763491] [] pci_iommu_init+0x28/0x52 [ 14.769846] [] do_one_initcall+0x122/0x180 [ 14.776506] [] ? parse_args+0x1e8/0x320 [ 14.782866] [] kernel_init_freeable+0x1e1/0x26c [ 14.789994] [] ? do_early_param+0x88/0x88 [ 14.796556] [] ? rest_init+0xd0/0xd0 [ 14.802626] [] kernel_init+0xe/0x130 [ 14.808698] [] ret_from_fork+0x7c/0xb0 [ 14.814963] [] ? rest_init+0xd0/0xd0 [ 14.821640] kmem_cache_destroy iommu_domain: Slab cache still has objects [ 14.829456] CPU: 12 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc1-gerry+ #59 [ 14.837562] Hardware name: Intel Corporation LH Pass ../SVRBD-ROW_T, BIOS SE5C600.86B.99.99.x059.091020121352 09/10/2012 [ 14.850803] 88042dd33db0 8156223d 88102c1ee3c0 [ 14.861222] 88042dd33dc8 811790b1 880c2d3533b8 88042dd33e00 [ 14.870284] 81dc7a76 81b1e8e0 81f84058 81d8a711 [ 14.879271] Call Trace: [ 14.882227] [] dump_stack+0x4d/0x66 [ 14.888197] [] kmem_cache_destroy+0xf1/0x100 [ 14.895034] [] intel_iommu_init+0x12e/0x56a [ 14.901781] [] ? iommu_setup+0x27d/0x27d [ 14.908238] [] pci_iommu_init+0x28/0x52 [ 14.914594] [] do_one_initcall+0x122/0x180 [ 14.921244] [] ? parse_args+0x1e8/0x320 [ 14.927598] [] kernel_init_freeable+0x1e1/0x26c [ 14.934738] [] ? do_early_param+0x88/0x88 [ 14.941309] [] ? rest_init+0xd0/0xd0 [ 14.947380] [] kernel_init+0xe/0x130 [ 14.953430] [] ret_from_fork+0x7c/0xb0 [ 14.959689] [] ? rest_init+0xd0/0xd0 [ 14.966299] kmem_cache_destroy iommu_iova: Slab cache still has objects [ 14.973923] CPU: 12 PID: 1 Comm: swapper/0 Not tainted 3.13.0-rc1-gerry+ #59 [ 14.982020] Hardware name: Intel Corporation LH Pass ../SVRBD-ROW_T, BIOS SE5C600.86B.99.99.x059.091020121352 09/10/2012 [ 14.995263] 88042dd33db0 8156223d 88042cb5c980 [ 15.004265] 88042dd33dc8 811790b1 880c2d3533b8 88042dd33e00 [ 15.013322] 81dc7a82 81b1e8e0 81f84058 81d8a711 [ 15.022318] Call Trace: [ 15.025238] [] dump_stack+0x4d/0x66 [ 15.031202] [] kmem_cache_destroy+0xf1/0x100 [ 15.038038] [] intel_iommu_init+0x13a/0x56a [ 15.044786] [] ? iommu_setup+0x27d/0x27d [ 15.051242] [] pci_iommu_init+0x28/0x52 [ 15.057601] [] do_one_initcall+0x122/0x180 [ 15.064254] [] ? parse_args+0x1e8/0x320 [ 15.070608] [] kernel_init_freeable+0x1e1/0x26c [ 15.077747] [] ? do_early_param+0x88/0x88 [ 15.084300] [] ? rest_init+0xd0/0xd0 [ 15.090362] [] kernel_init+0xe/0x130 [ 15.096431] [] ret_from_fork+0x7c/0xb0 [ 15.102693] [] ? rest_init+0xd0/0xd0 [ 15.189273] PCI-DMA: Using software bounce buffering for IO (SWIOTLB) Signed-off-by: Jiang Liu Cc: Alex Williamson --- drivers/iommu/intel-iommu.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 6724772..a27d3eb 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1365,6 +1365,7 @@ static int iommu_attach_domain(struct dmar_domain *domain, } domain->id = num; + domain->iommu_count++; set_bit(num, iommu->domain_ids); set_bit(iommu->seq_id, domain->iommu_bmp); iommu->domains[num] = domain; @@ -1489,7 +1490,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width) domain->iommu_snooping = 0;
[Patch Part2 V2 07/17] iommu/vt-d: free resources if failed to create domain for PCIe endpoint
Enhance function get_domain_for_dev() to release allocated resources if failed to create domain for PCIe endpoint, otherwise the allocated resources will get lost. Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 67b114e..503cc73 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -2015,7 +2015,7 @@ static int dmar_insert_dev_info(int segment, int bus, int devfn, /* domain is initialized */ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) { - struct dmar_domain *domain; + struct dmar_domain *domain, *free = NULL; struct intel_iommu *iommu; struct dmar_drhd_unit *drhd; struct pci_dev *dev_tmp; @@ -2062,17 +2062,16 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) free_domain_mem(domain); goto error; } - if (domain_init(domain, gaw)) { - domain_exit(domain); + free = domain; + if (domain_init(domain, gaw)) goto error; - } /* register pcie-to-pci device */ if (dev_tmp) { - if (dmar_insert_dev_info(segment, bus, devfn, NULL, &domain)) { - domain_exit(domain); + if (dmar_insert_dev_info(segment, bus, devfn, NULL, &domain)) goto error; - } + else + free = NULL; } found_domain: @@ -2080,6 +2079,8 @@ found_domain: pdev, &domain) == 0) return domain; error: + if (free) + domain_exit(free); /* recheck it here, maybe others set it */ return find_domain(pdev); } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch Part2 V2 16/17] iommu/vt-d, PCI: unify the way to process DMAR device scope array
Now we have a PCI bus notification based mechanism to update DMAR device scope array, we could extend the mechanism to support boot time initialization too, which will help to unify and simplify the implementation. Signed-off-by: Jiang Liu --- drivers/iommu/dmar.c| 163 --- drivers/iommu/intel-iommu.c | 71 +-- include/linux/dmar.h|5 -- 3 files changed, 61 insertions(+), 178 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index bf6bfd1..b19f9f4 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -60,6 +60,7 @@ LIST_HEAD(dmar_drhd_units); struct acpi_table_header * __initdata dmar_tbl; static acpi_size dmar_tbl_size; +static int dmar_dev_scope_status = 1; static int alloc_iommu(struct dmar_drhd_unit *drhd); static void free_iommu(struct intel_iommu *iommu); @@ -76,58 +77,6 @@ static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd) list_add_rcu(&drhd->list, &dmar_drhd_units); } -static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, - struct pci_dev __rcu **dev, u16 segment) -{ - struct pci_bus *bus; - struct pci_dev *pdev = NULL; - struct acpi_dmar_pci_path *path; - int count; - - bus = pci_find_bus(segment, scope->bus); - path = (struct acpi_dmar_pci_path *)(scope + 1); - count = (scope->length - sizeof(struct acpi_dmar_device_scope)) - / sizeof(struct acpi_dmar_pci_path); - - while (count) { - if (pdev) - pci_dev_put(pdev); - /* -* Some BIOSes list non-exist devices in DMAR table, just -* ignore it -*/ - if (!bus) { - pr_warn("Device scope bus [%d] not found\n", scope->bus); - break; - } - pdev = pci_get_slot(bus, PCI_DEVFN(path->device, path->function)); - if (!pdev) { - /* warning will be printed below */ - break; - } - path ++; - count --; - bus = pdev->subordinate; - } - if (!pdev) { - pr_warn("Device scope device [%04x:%02x:%02x.%02x] not found\n", - segment, scope->bus, path->device, path->function); - return 0; - } - if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT && \ - pdev->subordinate) || (scope->entry_type == \ - ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) { - pci_dev_put(pdev); - pr_warn("Device scope type does not match for %s\n", - pci_name(pdev)); - return -EINVAL; - } - - rcu_assign_pointer(*dev, pdev); - - return 0; -} - void *dmar_alloc_dev_scope(void *start, void *end, int *cnt) { struct acpi_dmar_device_scope *scope; @@ -150,35 +99,6 @@ void *dmar_alloc_dev_scope(void *start, void *end, int *cnt) return kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL); } -int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, - struct pci_dev __rcu ***devices, u16 segment) -{ - struct acpi_dmar_device_scope *scope; - int index, ret; - - *devices = dmar_alloc_dev_scope(start, end, cnt); - if (*cnt == 0) - return 0; - else if (!*devices) - return -ENOMEM; - - for (index = 0; start < end; start += scope->length) { - scope = start; - if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT || - scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) { - ret = dmar_parse_one_dev_scope(scope, - &(*devices)[index], segment); - if (ret) { - dmar_free_dev_scope(devices, cnt); - return ret; - } - index ++; - } - } - - return 0; -} - void dmar_free_dev_scope(struct pci_dev __rcu ***devices, int *cnt) { int i; @@ -220,6 +140,8 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) if (!info) { pr_warn("Out of memory when allocating notify_info " "for %s.\n", pci_name(dev)); + if (dmar_dev_scope_status == 0) + dmar_dev_scope_status = -ENOMEM; return NULL; } } @@ -349,6 +271,8 @@ static int dmar_pci_bus_add_dev(struct dmar_pci_notify_info *info) } if (ret >= 0) ret = dmar_iommu_notify_scope_dev(info); + if (ret < 0 && dmar_
[Patch Part2 V2 12/17] iommu/vt-d: introduce macro for_each_dev_scope() to walk device scope entries
Introduce for_each_dev_scope()/for_each_active_dev_scope() to walk {active} device scope entries. This will help following RCU lock related patches. Signed-off-by: Jiang Liu --- drivers/iommu/dmar.c| 14 +++--- drivers/iommu/intel-iommu.c | 100 +-- include/linux/dmar.h|6 +++ 3 files changed, 64 insertions(+), 56 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 58dde75..4ae6df2 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -170,9 +170,12 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt) { + int i; + struct pci_dev *tmp_dev; + if (*devices && *cnt) { - while (--*cnt >= 0) - pci_dev_put((*devices)[*cnt]); + for_each_active_dev_scope(*devices, *cnt, i, tmp_dev) + pci_dev_put(tmp_dev); kfree(*devices); *devices = NULL; *cnt = 0; @@ -402,10 +405,11 @@ static int dmar_pci_device_match(struct pci_dev *devices[], int cnt, struct pci_dev *dev) { int index; + struct pci_dev *tmp; while (dev) { - for (index = 0; index < cnt; index++) - if (dev == devices[index]) + for_each_active_dev_scope(devices, cnt, index, tmp) + if (dev == tmp) return 1; /* Check our parent */ @@ -452,7 +456,7 @@ int __init dmar_dev_scope_init(void) if (list_empty(&dmar_drhd_units)) goto fail; - list_for_each_entry(drhd, &dmar_drhd_units, list) { + for_each_drhd_unit(drhd) { ret = dmar_parse_dev(drhd); if (ret) goto fail; diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 7732c43..bb98e37 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -654,29 +654,31 @@ static void domain_update_iommu_cap(struct dmar_domain *domain) static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn) { struct dmar_drhd_unit *drhd = NULL; + struct intel_iommu *iommu; + struct pci_dev *dev; int i; - for_each_active_drhd_unit(drhd) { + for_each_active_iommu(iommu, drhd) { if (segment != drhd->segment) continue; - for (i = 0; i < drhd->devices_cnt; i++) { - if (drhd->devices[i] && - drhd->devices[i]->bus->number == bus && - drhd->devices[i]->devfn == devfn) - return drhd->iommu; - if (drhd->devices[i] && - drhd->devices[i]->subordinate && - drhd->devices[i]->subordinate->number <= bus && - drhd->devices[i]->subordinate->busn_res.end >= bus) - return drhd->iommu; + for_each_active_dev_scope(drhd->devices, + drhd->devices_cnt, i, dev) { + if (dev->bus->number == bus && dev->devfn == devfn) + goto out; + if (dev->subordinate && + dev->subordinate->number <= bus && + dev->subordinate->busn_res.end >= bus) + goto out; } if (drhd->include_all) - return drhd->iommu; + goto out; } + iommu = NULL; +out: - return NULL; + return iommu; } static void domain_flush_cache(struct dmar_domain *domain, @@ -2333,17 +2335,19 @@ static int domain_add_dev_info(struct dmar_domain *domain, static bool device_has_rmrr(struct pci_dev *dev) { struct dmar_rmrr_unit *rmrr; + struct pci_dev *tmp; int i; for_each_rmrr_units(rmrr) { - for (i = 0; i < rmrr->devices_cnt; i++) { - /* -* Return TRUE if this RMRR contains the device that -* is passed in. -*/ - if (rmrr->devices[i] == dev) + /* +* Return TRUE if this RMRR contains the device that +* is passed in. +*/ + for_each_active_dev_scope(rmrr->devices, + rmrr->devices_cnt, i, tmp) + if (tmp == dev) { return true; - } + } } return false; } @@ -2593,14 +2597,9 @@ static int __init init_dmars(void) */ printk(KERN_INFO "IOMMU: Setting RMRR:\n"); f
[Patch Part2 V2 10/17] iommu/vt-d: check for NULL pointer when freeing IOMMU data structure
Domain id 0 will be assigned to invalid translation without allocating domain data structure if DMAR unit supports caching mode. So in function free_dmar_iommu(), we should check whether the domain pointer is NULL, otherwise it will cause system crash as below: [6.790519] BUG: unable to handle kernel NULL pointer dereference at 00c8 [6.799520] IP: [] __lock_acquire+0x11f8/0x1430 [6.806493] PGD 0 [6.817972] Oops: [#1] SMP DEBUG_PAGEALLOC [6.823303] Modules linked in: [6.826862] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.14.0-rc1+ #126 [6.834252] Hardware name: Intel Corporation BRICKLAND/BRICKLAND, BIOS BRIVTIN1.86B.0047.R00.1402050741 02/05/2014 [6.845951] task: 880455a8 ti: 880455a88000 task.ti: 880455a88000 [6.854437] RIP: 0010:[] [] __lock_acquire+0x11f8/0x1430 [6.864154] RSP: :880455a89ce0 EFLAGS: 00010046 [6.870179] RAX: 0046 RBX: 0002 RCX: [6.878249] RDX: RSI: RDI: 00c8 [6.886318] RBP: 880455a89d40 R08: 0002 R09: 0001 [6.894387] R10: R11: 0001 R12: 880455a8 [6.902458] R13: R14: 00c8 R15: [6.910520] FS: () GS:88045b80() knlGS: [6.919687] CS: 0010 DS: ES: CR0: 80050033 [6.926198] CR2: 00c8 CR3: 01e0e000 CR4: 001407f0 [6.934269] Stack: [6.936588] ff10 810f59db 0010 0246 [6.945219] 880455a89d10 82bcb980 0046 [6.953850] 0002 [6.962482] Call Trace: [6.965300] [] ? vprintk_emit+0x4fb/0x5a0 [6.971716] [] lock_acquire+0x185/0x200 [6.977941] [] ? init_dmars+0x839/0xa1d [6.984167] [] _raw_spin_lock_irqsave+0x56/0x90 [6.991158] [] ? init_dmars+0x839/0xa1d [6.997380] [] init_dmars+0x839/0xa1d [7.003410] [] ? pci_get_dev_by_id+0x75/0xd0 [7.010119] [] intel_iommu_init+0x2f0/0x502 [7.016735] [] ? iommu_setup+0x27d/0x27d [7.023056] [] pci_iommu_init+0x28/0x52 [7.029282] [] do_one_initcall+0xf2/0x220 [7.035702] [] ? parse_args+0x2c9/0x450 [7.041919] [] kernel_init_freeable+0x1c9/0x25b [7.048919] [] ? do_early_param+0x8a/0x8a [7.055336] [] ? rest_init+0x150/0x150 [7.061461] [] kernel_init+0xe/0x100 [7.067393] [] ret_from_fork+0x7c/0xb0 [7.073518] [] ? rest_init+0x150/0x150 [7.079642] Code: 01 76 18 89 05 46 04 36 01 41 be 01 00 00 00 e9 2f 02 00 00 0f 1f 80 00 00 00 00 41 be 01 00 00 00 e9 1d 02 00 00 0f 1f 44 00 00 <49> 81 3e c0 31 34 82 b8 01 00 00 00 0f 44 d8 41 83 ff 01 0f 87 [7.104944] RIP [] __lock_acquire+0x11f8/0x1430 [7.112008] RSP [7.115988] CR2: 00c8 [7.119784] ---[ end trace 13d756f0f462c538 ]--- [7.125034] note: swapper/0[1] exited with preempt_count 1 [7.131285] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0009 [7.131285] Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c |7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index a27d3eb..afbc8d6 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1297,6 +1297,13 @@ static void free_dmar_iommu(struct intel_iommu *iommu) if ((iommu->domains) && (iommu->domain_ids)) { for_each_set_bit(i, iommu->domain_ids, cap_ndoms(iommu->cap)) { + /* +* Domain id 0 is reserved for invalid translation +* if hardware supports caching mode. +*/ + if (cap_caching_mode(iommu->cap) && i == 0) + continue; + domain = iommu->domains[i]; clear_bit(i, iommu->domain_ids); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch Part2 V2 14/17] iommu/vt-d: use RCU to protect global resources in interrupt context
Global DMA and interrupt remapping resources may be accessed in interrupt context, so use RCU instead of rwsem to protect them in such cases. Signed-off-by: Jiang Liu --- drivers/iommu/dmar.c| 33 - drivers/iommu/intel-iommu.c | 20 include/linux/dmar.h| 23 +-- 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index c9aca88..6e4d851 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -71,13 +71,13 @@ static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd) * the very end. */ if (drhd->include_all) - list_add_tail(&drhd->list, &dmar_drhd_units); + list_add_tail_rcu(&drhd->list, &dmar_drhd_units); else - list_add(&drhd->list, &dmar_drhd_units); + list_add_rcu(&drhd->list, &dmar_drhd_units); } static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, - struct pci_dev **dev, u16 segment) + struct pci_dev __rcu **dev, u16 segment) { struct pci_bus *bus; struct pci_dev *pdev = NULL; @@ -122,7 +122,9 @@ static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope, pci_name(pdev)); return -EINVAL; } - *dev = pdev; + + rcu_assign_pointer(*dev, pdev); + return 0; } @@ -149,7 +151,7 @@ void *dmar_alloc_dev_scope(void *start, void *end, int *cnt) } int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, - struct pci_dev ***devices, u16 segment) + struct pci_dev __rcu ***devices, u16 segment) { struct acpi_dmar_device_scope *scope; int index, ret; @@ -177,7 +179,7 @@ int __init dmar_parse_dev_scope(void *start, void *end, int *cnt, return 0; } -void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt) +void dmar_free_dev_scope(struct pci_dev __rcu ***devices, int *cnt) { int i; struct pci_dev *tmp_dev; @@ -186,9 +188,10 @@ void dmar_free_dev_scope(struct pci_dev ***devices, int *cnt) for_each_active_dev_scope(*devices, *cnt, i, tmp_dev) pci_dev_put(tmp_dev); kfree(*devices); - *devices = NULL; - *cnt = 0; } + + *devices = NULL; + *cnt = 0; } /** @@ -410,7 +413,7 @@ parse_dmar_table(void) return ret; } -static int dmar_pci_device_match(struct pci_dev *devices[], int cnt, +static int dmar_pci_device_match(struct pci_dev __rcu *devices[], int cnt, struct pci_dev *dev) { int index; @@ -431,11 +434,12 @@ static int dmar_pci_device_match(struct pci_dev *devices[], int cnt, struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev) { - struct dmar_drhd_unit *dmaru = NULL; + struct dmar_drhd_unit *dmaru; struct acpi_dmar_hardware_unit *drhd; dev = pci_physfn(dev); + rcu_read_lock(); for_each_drhd_unit(dmaru) { drhd = container_of(dmaru->hdr, struct acpi_dmar_hardware_unit, @@ -443,14 +447,17 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev) if (dmaru->include_all && drhd->segment == pci_domain_nr(dev->bus)) - return dmaru; + goto out; if (dmar_pci_device_match(dmaru->devices, dmaru->devices_cnt, dev)) - return dmaru; + goto out; } + dmaru = NULL; +out: + rcu_read_unlock(); - return NULL; + return dmaru; } int __init dmar_dev_scope_init(void) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 50d639a..e1679a6 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -385,14 +385,14 @@ struct dmar_rmrr_unit { struct acpi_dmar_header *hdr; /* ACPI header */ u64 base_address; /* reserved base address*/ u64 end_address;/* reserved end address */ - struct pci_dev **devices; /* target devices */ + struct pci_dev __rcu **devices; /* target devices */ int devices_cnt;/* target device count */ }; struct dmar_atsr_unit { struct list_head list; /* list of ATSR units */ struct acpi_dmar_header *hdr; /* ACPI header */ - struct pci_dev **devices; /* target devices */ + struct pci_dev __rcu **devices; /* target devices */ int devices_cnt;/* target device count */ u8 include_all:1; /* include all ports */
[Patch Part2 V2 13/17] iommu/vt-d: introduce a rwsem to protect global data structures
Introduce a global rwsem dmar_global_lock, which will be used to protect DMAR related global data structures from DMAR/PCI/memory device hotplug operations in process context. DMA and interrupt remapping related data structures are read most, and only change when memory/PCI/DMAR hotplug event happens. So a global rwsem solution is adopted for balance between simplicity and performance. For interrupt remapping driver, function intel_irq_remapping_supported(), dmar_table_init(), intel_enable_irq_remapping(), disable_irq_remapping(), reenable_irq_remapping() and enable_drhd_fault_handling() etc are called during booting, suspending and resuming with interrupt disabled, so no need to take the global lock. For interrupt remapping entry allocation, the locking model is: down_read(&dmar_global_lock); /* Find corresponding iommu */ iommu = map_hpet_to_ir(id); if (iommu) /* * Allocate remapping entry and mark entry busy, * the IOMMU won't be hot-removed until the * allocated entry has been released. */ index = alloc_irte(iommu, irq, 1); up_read(&dmar_global_lock); For DMA remmaping driver, we only uses the dmar_global_lock rwsem to protect functions which are only called in process context. For any function which may be called in interrupt context, we will use RCU to protect them in following patches. Signed-off-by: Jiang Liu --- drivers/iommu/dmar.c| 19 +- drivers/iommu/intel-iommu.c | 22 --- drivers/iommu/intel_irq_remapping.c | 108 +++ include/linux/dmar.h|2 + 4 files changed, 103 insertions(+), 48 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 4ae6df2..c9aca88 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -43,10 +43,19 @@ #include "irq_remapping.h" -/* No locks are needed as DMA remapping hardware unit - * list is constructed at boot time and hotplug of - * these units are not supported by the architecture. +/* + * Assumptions: + * 1) The hotplug framework guarentees that DMAR unit will be hot-added + *before IO devices managed by that unit. + * 2) The hotplug framework guarantees that DMAR unit will be hot-removed + *after IO devices managed by that unit. + * 3) Hotplug events are rare. + * + * Locking rules for DMA and interrupt remapping related global data structures: + * 1) Use dmar_global_lock in process context + * 2) Use RCU in interrupt context */ +DECLARE_RWSEM(dmar_global_lock); LIST_HEAD(dmar_drhd_units); struct acpi_table_header * __initdata dmar_tbl; @@ -565,6 +574,7 @@ int __init detect_intel_iommu(void) { int ret; + down_write(&dmar_global_lock); ret = dmar_table_detect(); if (ret) ret = check_zero_address(); @@ -582,6 +592,7 @@ int __init detect_intel_iommu(void) } early_acpi_os_unmap_memory((void __iomem *)dmar_tbl, dmar_tbl_size); dmar_tbl = NULL; + up_write(&dmar_global_lock); return ret ? 1 : -ENODEV; } @@ -1394,10 +1405,12 @@ static int __init dmar_free_unused_resources(void) if (irq_remapping_enabled || intel_iommu_enabled) return 0; + down_write(&dmar_global_lock); list_for_each_entry_safe(dmaru, dmaru_n, &dmar_drhd_units, list) { list_del(&dmaru->list); dmar_free_drhd(dmaru); } + up_write(&dmar_global_lock); return 0; } diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index bb98e37..50d639a 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3637,11 +3637,13 @@ static int device_notifier(struct notifier_block *nb, if (!domain) return 0; + down_read(&dmar_global_lock); domain_remove_one_dev_info(domain, pdev); if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) && list_empty(&domain->devices)) domain_exit(domain); + up_read(&dmar_global_lock); return 0; } @@ -3659,6 +3661,13 @@ int __init intel_iommu_init(void) /* VT-d is required for a TXT/tboot launch, so enforce that */ force_on = tboot_force_iommu(); + if (iommu_init_mempool()) { + if (force_on) + panic("tboot: Failed to initialize iommu memory\n"); + return -ENOMEM; + } + + down_write(&dmar_global_lock); if (dmar_table_init()) { if (force_on) panic("tboot: Failed to initialize DMAR table\n"); @@ -3681,12 +3690,6 @@ int __init intel_iommu_init(void) if (no_iommu || dmar_disabled) goto out_free_dmar; - if (iommu_init_mempool()) { - if (force_on) - pani
[Patch Part2 V2 11/17] iommu/vt-d: fix error in detect ATS capability
Current Intel IOMMU driver only matches a PCIe root port with the first DRHD unit with the samge segment number. It will report false result if there are multiple DRHD units with the same segment number, thus fail to detect ATS capability for some PCIe devices. This patch refines function dmar_find_matched_atsr_unit() to search all DRHD units with the same segment number. An example DMAR table entries as below: [1D0h 0464 2]Subtable Type : 0002 [1D2h 0466 2] Length : 0028 [1D4h 0468 1]Flags : 00 [1D5h 0469 1] Reserved : 00 [1D6h 0470 2] PCI Segment Number : [1D8h 0472 1] Device Scope Entry Type : 02 [1D9h 0473 1] Entry Length : 08 [1DAh 0474 2] Reserved : [1DCh 0476 1] Enumeration ID : 00 [1DDh 0477 1] PCI Bus Number : 00 [1DEh 0478 2] PCI Path : [02, 00] [1E0h 0480 1] Device Scope Entry Type : 02 [1E1h 0481 1] Entry Length : 08 [1E2h 0482 2] Reserved : [1E4h 0484 1] Enumeration ID : 00 [1E5h 0485 1] PCI Bus Number : 00 [1E6h 0486 2] PCI Path : [03, 00] [1E8h 0488 1] Device Scope Entry Type : 02 [1E9h 0489 1] Entry Length : 08 [1EAh 0490 2] Reserved : [1ECh 0492 1] Enumeration ID : 00 [1EDh 0493 1] PCI Bus Number : 00 [1EEh 0494 2] PCI Path : [03, 02] [1F0h 0496 1] Device Scope Entry Type : 02 [1F1h 0497 1] Entry Length : 08 [1F2h 0498 2] Reserved : [1F4h 0500 1] Enumeration ID : 00 [1F5h 0501 1] PCI Bus Number : 00 [1F6h 0502 2] PCI Path : [03, 03] [1F8h 0504 2]Subtable Type : 0002 [1FAh 0506 2] Length : 0020 [1FCh 0508 1]Flags : 00 [1FDh 0509 1] Reserved : 00 [1FEh 0510 2] PCI Segment Number : [200h 0512 1] Device Scope Entry Type : 02 [201h 0513 1] Entry Length : 08 [202h 0514 2] Reserved : [204h 0516 1] Enumeration ID : 00 [205h 0517 1] PCI Bus Number : 40 [206h 0518 2] PCI Path : [02, 00] [208h 0520 1] Device Scope Entry Type : 02 [209h 0521 1] Entry Length : 08 [20Ah 0522 2] Reserved : [20Ch 0524 1] Enumeration ID : 00 [20Dh 0525 1] PCI Bus Number : 40 [20Eh 0526 2] PCI Path : [02, 02] [210h 0528 1] Device Scope Entry Type : 02 [211h 0529 1] Entry Length : 08 [212h 0530 2] Reserved : [214h 0532 1] Enumeration ID : 00 [215h 0533 1] PCI Bus Number : 40 [216h 0534 2] PCI Path : [03, 00] [218h 0536 2]Subtable Type : 0002 [21Ah 0538 2] Length : 0020 [21Ch 0540 1]Flags : 00 [21Dh 0541 1] Reserved : 00 [21Eh 0542 2] PCI Segment Number : [220h 0544 1] Device Scope Entry Type : 02 [221h 0545 1] Entry Length : 08 [222h 0546 2] Reserved : [224h 0548 1] Enumeration ID : 00 [225h 0549 1] PCI Bus Number : 80 [226h 0550 2] PCI Path : [02, 00] [228h 0552 1] Device Scope Entry Type : 02 [229h 0553 1] Entry Length : 08 [22Ah 0554 2] Reserved : [22Ch 0556 1] Enumeration ID : 00 [22Dh 0557 1] PCI Bus Number : 80 [22Eh 0558 2] PCI Path : [02, 02] [230h 0560 1] Device Scope Entry Type : 02 [231h 0561 1] Entry Length : 08 [232h 0562 2] Reserved : [234h 0564 1] Enumeration ID : 00 [235h 0565 1] PCI Bus Number : 80 [236h 0566 2] PCI Path : [03, 00] [238h 0568 2]Subtable Type : 0002 [23Ah 0570 2] Length : 0020 [23Ch 0572 1]Flags : 00 [23Dh 0573 1] Reserved : 00 [23Eh 0574 2] PCI Segment Number : [240h 0576 1] Device Scope Entry Type : 02 [241h 0577 1] Entry Length : 08 [242h 0578 2] Reserved : [244h 0580 1] Enumeration ID : 00 [245h 0581 1] PCI Bus Number : C0 [246h 0582 2] PCI Path : [02, 00] [248h 0584 1] Device Scope Entry Type : 02 [249h 0585 1] Entry Length : 08 [24Ah 0586 2] Reserved : [24Ch 0588 1] Enumeration ID : 00 [24Dh 0589 1] PCI Bus Nu
[Patch Part2 V2 15/17] iommu/vt-d, PCI: update DRHD/RMRR/ATSR device scope caches when PCI hotplug happens
Current Intel DMAR/IOMMU driver assumes that all PCI devices associated with DMAR/RMRR/ATSR device scope arrays are created at boot time and won't change at runtime, so it caches pointers of associated PCI device object. That assumption may be wrong now due to: 1) introduction of PCI host bridge hotplug 2) PCI device hotplug through sysfs interfaces. Wang Yijing has tried to solve this issue by caching tupple instead of the PCI device object pointer, but that's still unreliable because PCI bus number may change in case of hotplug. Please refer to http://lkml.org/lkml/2013/11/5/64 Message from Yingjing's mail: after remove and rescan a pci device [ 611.857095] dmar: DRHD: handling fault status reg 2 [ 611.857109] dmar: DMAR:[DMA Read] Request device [86:00.3] fault addr 7000 [ 611.857109] DMAR:[fault reason 02] Present bit in context entry is clear [ 611.857524] dmar: DRHD: handling fault status reg 102 [ 611.857534] dmar: DMAR:[DMA Read] Request device [86:00.3] fault addr 6000 [ 611.857534] DMAR:[fault reason 02] Present bit in context entry is clear [ 611.857936] dmar: DRHD: handling fault status reg 202 [ 611.857947] dmar: DMAR:[DMA Read] Request device [86:00.3] fault addr 5000 [ 611.857947] DMAR:[fault reason 02] Present bit in context entry is clear [ 611.858351] dmar: DRHD: handling fault status reg 302 [ 611.858362] dmar: DMAR:[DMA Read] Request device [86:00.3] fault addr 4000 [ 611.858362] DMAR:[fault reason 02] Present bit in context entry is clear [ 611.860819] IPv6: ADDRCONF(NETDEV_UP): eth3: link is not ready [ 611.860983] dmar: DRHD: handling fault status reg 402 [ 611.860995] dmar: INTR-REMAP: Request device [[86:00.3] fault index a4 [ 611.860995] INTR-REMAP:[fault reason 34] Present field in the IRTE entry is clear This patch introduces a new mechanism to update the DRHD/RMRR/ATSR device scope caches by hooking PCI bus notification. Signed-off-by: Jiang Liu --- drivers/iommu/dmar.c| 207 +++ drivers/iommu/intel-iommu.c | 54 +++ include/linux/dmar.h| 24 - 3 files changed, 283 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 6e4d851..bf6bfd1 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -194,6 +194,209 @@ void dmar_free_dev_scope(struct pci_dev __rcu ***devices, int *cnt) *cnt = 0; } +/* Optimize out kzalloc()/kfree() for normal cases */ +static char dmar_pci_notify_info_buf[64]; + +static struct dmar_pci_notify_info * +dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) +{ + int level = 0; + size_t size; + struct pci_dev *tmp; + struct dmar_pci_notify_info *info; + + BUG_ON(dev->is_virtfn); + + /* Only generate path[] for device addition event */ + if (event == BUS_NOTIFY_ADD_DEVICE) + for (tmp = dev; tmp; tmp = tmp->bus->self) + level++; + + size = sizeof(*info) + level * sizeof(struct acpi_dmar_pci_path); + if (size <= sizeof(dmar_pci_notify_info_buf)) { + info = (struct dmar_pci_notify_info *)dmar_pci_notify_info_buf; + } else { + info = kzalloc(size, GFP_KERNEL); + if (!info) { + pr_warn("Out of memory when allocating notify_info " + "for %s.\n", pci_name(dev)); + return NULL; + } + } + + info->event = event; + info->dev = dev; + info->seg = pci_domain_nr(dev->bus); + info->level = level; + if (event == BUS_NOTIFY_ADD_DEVICE) { + for (tmp = dev, level--; tmp; tmp = tmp->bus->self) { + info->path[level].device = PCI_SLOT(tmp->devfn); + info->path[level].function = PCI_FUNC(tmp->devfn); + if (pci_is_root_bus(tmp->bus)) + info->bus = tmp->bus->number; + } + } + + return info; +} + +static inline void dmar_free_pci_notify_info(struct dmar_pci_notify_info *info) +{ + if ((void *)info != dmar_pci_notify_info_buf) + kfree(info); +} + +static bool dmar_match_pci_path(struct dmar_pci_notify_info *info, int bus, + struct acpi_dmar_pci_path *path, int count) +{ + int i; + + if (info->bus != bus) + return false; + if (info->level != count) + return false; + + for (i = 0; i < count; i++) { + if (path[i].device != info->path[i].device || + path[i].function != info->path[i].function) + return false; + } + + return true; +} + +/* Return: > 0 if match found, 0 if no match found, < 0 if error happens */ +int dmar_insert_dev_scope(struct dmar_pci_notify_info *info, + void *start, void*end, u16 segment, +
[Patch Part2 V2 17/17] iommu/vt-d: update IOMMU state when memory hotplug happens
If static identity domain is created, IOMMU driver needs to update si_domain page table when memory hotplug event happens. Otherwise PCI device DMA operations can't access the hot-added memory regions. Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c | 71 ++- drivers/iommu/iova.c| 64 ++ include/linux/iova.h|2 ++ 3 files changed, 130 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index dd576c0..484d669 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -3683,6 +3684,73 @@ static struct notifier_block device_nb = { .notifier_call = device_notifier, }; +static int intel_iommu_memory_notifier(struct notifier_block *nb, + unsigned long val, void *v) +{ + struct memory_notify *mhp = v; + unsigned long long start, end; + unsigned long start_vpfn, last_vpfn; + + switch (val) { + case MEM_GOING_ONLINE: + start = mhp->start_pfn << PAGE_SHIFT; + end = ((mhp->start_pfn + mhp->nr_pages) << PAGE_SHIFT) - 1; + if (iommu_domain_identity_map(si_domain, start, end)) { + pr_warn("dmar: failed to build identity map for [%llx-%llx]\n", + start, end); + return NOTIFY_BAD; + } + break; + + case MEM_OFFLINE: + case MEM_CANCEL_ONLINE: + start_vpfn = mm_to_dma_pfn(mhp->start_pfn); + last_vpfn = mm_to_dma_pfn(mhp->start_pfn + mhp->nr_pages - 1); + while (start_vpfn <= last_vpfn) { + struct iova *iova; + struct dmar_drhd_unit *drhd; + struct intel_iommu *iommu; + + iova = find_iova(&si_domain->iovad, start_vpfn); + if (iova == NULL) { + pr_debug("dmar: failed get IOVA for PFN %lx\n", +start_vpfn); + break; + } + + iova = split_and_remove_iova(&si_domain->iovad, iova, +start_vpfn, last_vpfn); + if (iova == NULL) { + pr_warn("dmar: failed to split IOVA PFN [%lx-%lx]\n", + start_vpfn, last_vpfn); + return NOTIFY_BAD; + } + + rcu_read_lock(); + for_each_active_iommu(iommu, drhd) + iommu_flush_iotlb_psi(iommu, si_domain->id, + iova->pfn_lo, + iova->pfn_hi - iova->pfn_lo + 1, 0); + rcu_read_unlock(); + dma_pte_clear_range(si_domain, iova->pfn_lo, + iova->pfn_hi); + dma_pte_free_pagetable(si_domain, iova->pfn_lo, + iova->pfn_hi); + + start_vpfn = iova->pfn_hi + 1; + free_iova_mem(iova); + } + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block intel_iommu_memory_nb = { + .notifier_call = intel_iommu_memory_notifier, + .priority = 0 +}; + int __init intel_iommu_init(void) { int ret = -ENODEV; @@ -3755,8 +3823,9 @@ int __init intel_iommu_init(void) init_iommu_pm_ops(); bus_set_iommu(&pci_bus_type, &intel_iommu_ops); - bus_register_notifier(&pci_bus_type, &device_nb); + if (si_domain && !hw_pass_through) + register_memory_notifier(&intel_iommu_memory_nb); intel_iommu_enabled = 1; diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index 67da6cff..f6b17e6 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -342,19 +342,30 @@ __is_range_overlap(struct rb_node *node, return 0; } +static inline struct iova * +alloc_and_init_iova(unsigned long pfn_lo, unsigned long pfn_hi) +{ + struct iova *iova; + + iova = alloc_iova_mem(); + if (iova) { + iova->pfn_lo = pfn_lo; + iova->pfn_hi = pfn_hi; + } + + return iova; +} + static struct iova * __insert_new_range(struct iova_domain *iovad, unsigned long pfn_lo, unsigned long pfn_hi) { struct iova *iova; - iova = alloc_iova_mem(); - if (!iova) - return iova; + iova = alloc_and_init_iova(pfn_lo, pfn_hi); + if (iova) + iova_insert_rbtree(&iovad->rbroot, iova); - iova->pfn_hi =
[Patch Part2 V2 05/17] iommu/vt-d: move private structures and variables into intel-iommu.c
Move private structures and variables into intel-iommu.c, which will help to simplify locking policy for hotplug. Also delete redundant declarations. Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c | 31 +-- include/linux/dmar.h| 23 +-- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 5a411e8..fffe3d1 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -380,6 +380,29 @@ struct device_domain_info { struct dmar_domain *domain; /* pointer to domain */ }; +struct dmar_rmrr_unit { + struct list_head list; /* list of rmrr units */ + struct acpi_dmar_header *hdr; /* ACPI header */ + u64 base_address; /* reserved base address*/ + u64 end_address;/* reserved end address */ + struct pci_dev **devices; /* target devices */ + int devices_cnt;/* target device count */ +}; + +struct dmar_atsr_unit { + struct list_head list; /* list of ATSR units */ + struct acpi_dmar_header *hdr; /* ACPI header */ + struct pci_dev **devices; /* target devices */ + int devices_cnt;/* target device count */ + u8 include_all:1; /* include all ports */ +}; + +static LIST_HEAD(dmar_atsr_units); +static LIST_HEAD(dmar_rmrr_units); + +#define for_each_rmrr_units(rmrr) \ + list_for_each_entry(rmrr, &dmar_rmrr_units, list) + static void flush_unmaps_timeout(unsigned long data); static DEFINE_TIMER(unmap_timer, flush_unmaps_timeout, 0, 0); @@ -403,6 +426,8 @@ static int timer_on; static long list_size; static void domain_remove_dev_info(struct dmar_domain *domain); +static void domain_remove_one_dev_info(struct dmar_domain *domain, + struct pci_dev *pdev); #ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON int dmar_disabled = 0; @@ -2243,8 +2268,6 @@ static int __init si_domain_init(int hw) return 0; } -static void domain_remove_one_dev_info(struct dmar_domain *domain, - struct pci_dev *pdev); static int identity_mapping(struct pci_dev *pdev) { struct device_domain_info *info; @@ -3432,8 +3455,6 @@ static void __init init_iommu_pm_ops(void) static inline void init_iommu_pm_ops(void) {} #endif /* CONFIG_PM */ -LIST_HEAD(dmar_rmrr_units); - static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr) { list_add(&rmrr->list, &dmar_rmrr_units); @@ -3470,8 +3491,6 @@ rmrr_parse_dev(struct dmar_rmrr_unit *rmrru) rmrr->segment); } -static LIST_HEAD(dmar_atsr_units); - int __init dmar_parse_one_atsr(struct acpi_dmar_header *hdr) { struct acpi_dmar_atsr *atsr; diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 1b08ce8..ea599d4 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -139,28 +139,7 @@ extern int arch_setup_dmar_msi(unsigned int irq); #ifdef CONFIG_INTEL_IOMMU extern int iommu_detected, no_iommu; -extern struct list_head dmar_rmrr_units; -struct dmar_rmrr_unit { - struct list_head list; /* list of rmrr units */ - struct acpi_dmar_header *hdr; /* ACPI header */ - u64 base_address; /* reserved base address*/ - u64 end_address;/* reserved end address */ - struct pci_dev **devices; /* target devices */ - int devices_cnt;/* target device count */ -}; - -#define for_each_rmrr_units(rmrr) \ - list_for_each_entry(rmrr, &dmar_rmrr_units, list) - -struct dmar_atsr_unit { - struct list_head list; /* list of ATSR units */ - struct acpi_dmar_header *hdr; /* ACPI header */ - struct pci_dev **devices; /* target devices */ - int devices_cnt;/* target device count */ - u8 include_all:1; /* include all ports */ -}; - -int dmar_parse_rmrr_atsr_dev(void); +extern int dmar_parse_rmrr_atsr_dev(void); extern int dmar_parse_one_rmrr(struct acpi_dmar_header *header); extern int dmar_parse_one_atsr(struct acpi_dmar_header *header); extern int intel_iommu_init(void); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch Part2 V2 00/17] Enhance DMAR drivers to handle PCI/memory hotplug events
Intel DMA/interrupt remapping drivers scan available PCI/memory devices at startup and cache discovered hardware topologies. They don't update cached information if PCI/memory hotplug event happens at runtime, then the stale information may break DMA/interrupt remapping logic. This patchset first (Patch 1-12) tries to introduces some helper functions and fixes several bugs, then (Patch 13,14) uses a global rwsem and RCU to protect global DMA/interrupt remapping data structures, and finally (Patch 15-17) hook PCI/memory hotplug events to update cached information. It's also a preparation for supporting of DMA/interrupt remapping hotplug. V1->V2: 1) fix more bugs in dealing with identify mapping domain 2) address round 1 review comments Jiang Liu (17): iommu/vt-d: avoid double free of g_iommus on error recovery path iommu/vt-d: avoid caching stale domain_device_info and fix memory leak iommu/vt-d: avoid caching stale domain_device_info when hot-removing PCI device iommu/vt-d: factor out dmar_alloc_dev_scope() for later reuse iommu/vt-d: move private structures and variables into intel-iommu.c iommu/vt-d: simplify function get_domain_for_dev() iommu/vt-d: free resources if failed to create domain for PCIe endpoint iommu/vt-d: reduce duplicated code to handle virtual machine domains iommu/vt-d: fix incorrect iommu_count for si_domain iommu/vt-d: check for NULL pointer when freeing IOMMU data structure iommu/vt-d: fix error in detect ATS capability iommu/vt-d: introduce macro for_each_dev_scope() to walk device scope entries iommu/vt-d: introduce a rwsem to protect global data structures iommu/vt-d: use RCU to protect global resources in interrupt context iommu/vt-d, PCI: update DRHD/RMRR/ATSR device scope caches when PCI hotplug happens iommu/vt-d, PCI: unify the way to process DMAR device scope array iommu/vt-d: update IOMMU state when memory hotplug happens drivers/iommu/dmar.c| 412 +-- drivers/iommu/intel-iommu.c | 750 ++- drivers/iommu/intel_irq_remapping.c | 108 +++-- drivers/iommu/iova.c| 64 ++- include/linux/dmar.h| 74 ++-- include/linux/iova.h|2 + 6 files changed, 848 insertions(+), 562 deletions(-) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] atm: libahci: replace obselete simple_strtoul() with kstrtouint()
From: Daeseok Youn Date: Wed, 19 Feb 2014 14:09:49 +0900 > From 18bd7236f36a248a0871f810cec3c1e98f098a91 Mon Sep 17 00:00:00 2001 > From: Daeseok Youn > Date: Wed, 19 Feb 2014 13:44:24 +0900 > Subject: [PATCH] atm: libahci: replace obselete simple_strtoul() with > kstrtouint() > > Signed-off-by: Daeseok Youn Please fix your Subject line, you meant "ata: " not "atm: " -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch v2 3/5] xen, acpi_pad: use acpi_evaluate_ost() to replace open-coded version
Use public function acpi_evaluate_ost() to replace open-coded version of evaluating ACPI _OST method. Signed-off-by: Jiang Liu --- drivers/xen/xen-acpi-pad.c | 26 +++--- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/xen/xen-acpi-pad.c b/drivers/xen/xen-acpi-pad.c index 40c4bc0..f83b754 100644 --- a/drivers/xen/xen-acpi-pad.c +++ b/drivers/xen/xen-acpi-pad.c @@ -77,27 +77,14 @@ static int acpi_pad_pur(acpi_handle handle) return num; } -/* Notify firmware how many CPUs are idle */ -static void acpi_pad_ost(acpi_handle handle, int stat, - uint32_t idle_nums) -{ - union acpi_object params[3] = { - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_BUFFER,}, - }; - struct acpi_object_list arg_list = {3, params}; - - params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY; - params[1].integer.value = stat; - params[2].buffer.length = 4; - params[2].buffer.pointer = (void *)&idle_nums; - acpi_evaluate_object(handle, "_OST", &arg_list, NULL); -} - static void acpi_pad_handle_notify(acpi_handle handle) { int idle_nums; + struct acpi_buffer param = { + .length = 4, + .pointer = (void *)&idle_nums, + }; + mutex_lock(&xen_cpu_lock); idle_nums = acpi_pad_pur(handle); @@ -109,7 +96,8 @@ static void acpi_pad_handle_notify(acpi_handle handle) idle_nums = xen_acpi_pad_idle_cpus(idle_nums) ?: xen_acpi_pad_idle_cpus_num(); if (idle_nums >= 0) - acpi_pad_ost(handle, 0, idle_nums); + acpi_evaluate_ost(handle, ACPI_PROCESSOR_AGGREGATOR_NOTIFY, + 0, ¶m); mutex_unlock(&xen_cpu_lock); } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch v2 4/5] acpi_processor: use acpi_evaluate_ost() to replace open-coded version
Use public function acpi_evaluate_ost() to replace open-coded version of evaluating ACPI _OST method. Signed-off-by: Jiang Liu --- drivers/acpi/processor_perflib.c | 14 +++--- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index ff90054..cfc8aba 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -156,17 +156,9 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) */ static void acpi_processor_ppc_ost(acpi_handle handle, int status) { - union acpi_object params[2] = { - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_INTEGER,}, - }; - struct acpi_object_list arg_list = {2, params}; - - if (acpi_has_method(handle, "_OST")) { - params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE; - params[1].integer.value = status; - acpi_evaluate_object(handle, "_OST", &arg_list, NULL); - } + if (acpi_has_method(handle, "_OST")) + acpi_evaluate_ost(handle, ACPI_PROCESSOR_NOTIFY_PERFORMANCE, + status, NULL); } int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch v2 2/5] acpi_pad: use acpi_evaluate_ost() to replace open-coded version
Use public function acpi_evaluate_ost() to replace open-coded version of evaluating ACPI _OST method. Signed-off-by: Jiang Liu --- drivers/acpi/acpi_pad.c | 24 +--- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index df96a0f..37d7302 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -408,28 +408,14 @@ static int acpi_pad_pur(acpi_handle handle) return num; } -/* Notify firmware how many CPUs are idle */ -static void acpi_pad_ost(acpi_handle handle, int stat, - uint32_t idle_cpus) -{ - union acpi_object params[3] = { - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_BUFFER,}, - }; - struct acpi_object_list arg_list = {3, params}; - - params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY; - params[1].integer.value = stat; - params[2].buffer.length = 4; - params[2].buffer.pointer = (void *)&idle_cpus; - acpi_evaluate_object(handle, "_OST", &arg_list, NULL); -} - static void acpi_pad_handle_notify(acpi_handle handle) { int num_cpus; uint32_t idle_cpus; + struct acpi_buffer param = { + .length = 4, + .pointer = (void *)&idle_cpus, + }; mutex_lock(&isolated_cpus_lock); num_cpus = acpi_pad_pur(handle); @@ -439,7 +425,7 @@ static void acpi_pad_handle_notify(acpi_handle handle) } acpi_pad_idle_cpus(num_cpus); idle_cpus = acpi_pad_idle_cpus_num(); - acpi_pad_ost(handle, 0, idle_cpus); + acpi_evaluate_ost(handle, ACPI_PROCESSOR_AGGREGATOR_NOTIFY, 0, ¶m); mutex_unlock(&isolated_cpus_lock); } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch v2 1/5] ACPI: rename acpi_evaluate_hotplug_ost to acpi_evaluate_ost for reuse
Rename acpi_evaluate_hotplug_ost() to acpi_evaluate_ost() for later resue. Signed-off-by: Jiang Liu --- drivers/acpi/utils.c| 14 -- include/acpi/acpi_bus.h | 10 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 85e3b61..19d0169 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -433,17 +433,15 @@ EXPORT_SYMBOL(acpi_get_physical_device_location); * When the platform does not support _OST, this function has no effect. */ acpi_status -acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, - u32 status_code, struct acpi_buffer *status_buf) +acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, + struct acpi_buffer *status_buf) { -#ifdef ACPI_HOTPLUG_OST union acpi_object params[3] = { {.type = ACPI_TYPE_INTEGER,}, {.type = ACPI_TYPE_INTEGER,}, {.type = ACPI_TYPE_BUFFER,} }; struct acpi_object_list arg_list = {3, params}; - acpi_status status; params[0].integer.value = source_event; params[1].integer.value = status_code; @@ -455,13 +453,9 @@ acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, params[2].buffer.length = 0; } - status = acpi_evaluate_object(handle, "_OST", &arg_list, NULL); - return status; -#else - return AE_OK; -#endif + return acpi_evaluate_object(handle, "_OST", &arg_list, NULL); } -EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); +EXPORT_SYMBOL(acpi_evaluate_ost); /** * acpi_handle_printk: Print message with ACPI prefix and object path diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 8256eb4..adef502 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -49,8 +49,16 @@ acpi_evaluate_reference(acpi_handle handle, struct acpi_object_list *arguments, struct acpi_handle_list *list); acpi_status +acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, + struct acpi_buffer *status_buf); +#ifdef ACPI_HOTPLUG_OST +#defineacpi_evaluate_hotplug_ost acpi_evaluate_ost +#else +static inline acpi_status acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, - u32 status_code, struct acpi_buffer *status_buf); + u32 status_code, struct acpi_buffer *status_buf) +{ return AE_OK; } +#endif acpi_status acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[Patch v2 5/5] ACPI: use device name LNXSYBUS.xx for ACPI \_SB and \_TZ objects
Use device name "LNXSYBUS:xx" instead of "device.xx" for ACPI objects \_SB and \_TZ. BTW, the original check of "handle == ACPI_ROOT_OBJECT" in statment "else if (list_empty(&pnp->ids) && handle == ACPI_ROOT_OBJECT)" is always false because of the code at the begin of that block. if (handle == ACPI_ROOT_OBJECT) { acpi_add_id(pnp, ACPI_SYSTEM_HID); break; } Signed-off-by: Jiang Liu --- drivers/acpi/scan.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 57b053f..62ec4ba 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1706,6 +1706,20 @@ static bool acpi_ibm_smbus_match(acpi_handle handle) return false; } +static bool acpi_object_is_system_bus(acpi_handle handle) +{ + acpi_handle tmp; + + if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_SB", &tmp)) && + tmp == handle) + return true; + if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_TZ", &tmp)) && + tmp == handle) + return true; + + return false; +} + static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, int device_type) { @@ -1757,8 +1771,10 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, acpi_add_id(pnp, ACPI_DOCK_HID); else if (acpi_ibm_smbus_match(handle)) acpi_add_id(pnp, ACPI_SMBUS_IBM_HID); - else if (list_empty(&pnp->ids) && handle == ACPI_ROOT_OBJECT) { - acpi_add_id(pnp, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ + else if (list_empty(&pnp->ids) && +acpi_object_is_system_bus(handle)) { + /* \_SB, \_TZ, LNXSYBUS */ + acpi_add_id(pnp, ACPI_BUS_HID); strcpy(pnp->device_name, ACPI_BUS_DEVICE_NAME); strcpy(pnp->device_class, ACPI_BUS_CLASS); } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC Patch v1 3/6] acpi_pad: use acpi_evaluate_pad() to replace open-coded version
Hi Rafael, Thanks for reminder, will fix it in next version. Cheers! Gerry On 2014/2/18 9:07, Rafael J. Wysocki wrote: > On Monday, February 17, 2014 01:02:50 PM Jiang Liu wrote: >> Use public function acpi_evaluate_pad() to replace open-coded > > I suppose you mean acpi_evaluate_ost()? And in the other patches > in this series too? > >> version of evaluating ACPI _OST method. >> >> Signed-off-by: Jiang Liu >> --- >> drivers/acpi/acpi_pad.c | 24 +--- >> 1 file changed, 5 insertions(+), 19 deletions(-) >> >> diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c >> index 1e3ce76..86b4e11 100644 >> --- a/drivers/acpi/acpi_pad.c >> +++ b/drivers/acpi/acpi_pad.c >> @@ -408,28 +408,14 @@ static int acpi_pad_pur(acpi_handle handle) >> return num; >> } >> >> -/* Notify firmware how many CPUs are idle */ >> -static void acpi_pad_ost(acpi_handle handle, int stat, >> -uint32_t idle_cpus) >> -{ >> -union acpi_object params[3] = { >> -{.type = ACPI_TYPE_INTEGER,}, >> -{.type = ACPI_TYPE_INTEGER,}, >> -{.type = ACPI_TYPE_BUFFER,}, >> -}; >> -struct acpi_object_list arg_list = {3, params}; >> - >> -params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY; >> -params[1].integer.value = stat; >> -params[2].buffer.length = 4; >> -params[2].buffer.pointer = (void *)&idle_cpus; >> -acpi_evaluate_object(handle, "_OST", &arg_list, NULL); >> -} >> - >> static void acpi_pad_handle_notify(acpi_handle handle) >> { >> int num_cpus; >> uint32_t idle_cpus; >> +struct acpi_buffer param = { >> +.length = 4, >> +.pointer = (void *)&idle_cpus, >> +}; >> >> mutex_lock(&isolated_cpus_lock); >> num_cpus = acpi_pad_pur(handle); >> @@ -439,7 +425,7 @@ static void acpi_pad_handle_notify(acpi_handle handle) >> } >> acpi_pad_idle_cpus(num_cpus); >> idle_cpus = acpi_pad_idle_cpus_num(); >> -acpi_pad_ost(handle, 0, idle_cpus); >> +acpi_evaluate_ost(handle, ACPI_PROCESSOR_AGGREGATOR_NOTIFY, 0, ¶m); >> mutex_unlock(&isolated_cpus_lock); >> } >> >> > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
introduction of www.xrefs.info
hello, I made http://www.xrefs.info available to open source community in the hope of making open source developers more productive. The site hosts many open source code projects' cross references based on OpenGrok, which is a very fast cross reference tool, and easy to use. To access, you can go to http://www.xrefs.info, select a project, pick a version. If you want to search the definition of a function, simply type it in the definition box; If you want to do a full search, type your text in the first box; If you want to search a file, simply type file name in file path box. Hit search button, That's it! The site covers following: - Linux kernel cross reference: from verion 0.01 - 3.13.3, plus nightly latest. - Linux boot loaders cross reference: u-boot, lilo, grub, syslinux,plus nightly latest. - Linux user space core packages cross reference - Android cross reference, plus nightly latest. - Cloud computing other projects: - xen hypervisor cross reference - VirtualBox cross reference; - OpenStack cross reference - cloudStack cross reference. - Puppet cross reference - Salt cross reference - Cloud Foundary cross reference - OpenShift cross reference - Chef cross reference - Juju cross reference - Big data project Hadoop cross reference - BSD: FreeBSD cross reference, NetBSD cross reference, DragonflyBSD cross reference - Database: MySQL cross reference, MariaDB cross reference, mongoDB cross reference - Languages: OpenJDK cross reference, Perl cross reference, Python cross reference, PHP cross reference. If you have any questions, comments or suggestions for the site, please let me know. Thanks. xrefs.i...@gmail.com -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
linux-next: Tree for Feb 19
Hi all, If you see failures in building this tree due to missing declarations of k..alloc/free, then it may be caused by commit 2bd59d48ebfb ("cgroup: convert to kernfs"). Please send Tejun Heo a patch adding an inclusion of linux/slab.h to the appropriate file(s). This tree fails (more than usual) the powerpc allyesconfig build. Changes since 20140218: The powerpc tree still had its build failure. The mfd-lj tree still had its build failure so I used the version from next-20140210. The sound-asoc tree gained a build failure for which I disabled a new driver. Non-merge commits (relative to Linus' tree): 3418 3600 files changed, 125777 insertions(+), 65737 deletions(-) I have created today's linux-next tree at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git (patches at http://www.kernel.org/pub/linux/kernel/next/ ). If you are tracking the linux-next tree using git, you should not use "git pull" to do so as that will try to merge the new linux-next release with the old one. You should use "git fetch" as mentioned in the FAQ on the wiki (see below). You can see which trees have been included by looking in the Next/Trees file in the source. There are also quilt-import.log and merge.log files in the Next directory. Between each merge, the tree was built with a ppc64_defconfig for powerpc and an allmodconfig for x86_64 and a multi_v7_defconfig for arm. After the final fixups (if any), it is also built with powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig and allyesconfig (minus CONFIG_PROFILE_ALL_BRANCHES - this fails its final link) and i386, sparc, sparc64 and arm defconfig. These builds also have CONFIG_ENABLE_WARN_DEPRECATED, CONFIG_ENABLE_MUST_CHECK and CONFIG_DEBUG_INFO disabled when necessary. Below is a summary of the state of the merge. I am currently merging 209 trees (counting Linus' and 28 trees of patches pending for Linus' tree). Stats about the size of the tree over time can be seen at http://neuling.org/linux-next-size.html . Status of my local build tests will be at http://kisskb.ellerman.id.au/linux-next . If maintainers want to give advice about cross compilers/configs that work, we are always open to add more builds. Thanks to Randy Dunlap for doing many randconfig builds. And to Paul Gortmaker for triage and bug fixes. There is a wiki covering stuff to do with linux-next at http://linux.f-seidel.de/linux-next/pmwiki/ . Thanks to Frank Seidel. -- Cheers, Stephen Rothwells...@canb.auug.org.au $ git checkout master $ git reset --hard stable Merging origin/master (91c6c8dcc7c3 Merge branch 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm) Merging fixes/master (b0031f227e47 Merge tag 's2mps11-build' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator) Merging kbuild-current/rc-fixes (38dbfb59d117 Linus 3.14-rc1) Merging arc-current/for-curr (7e22e91102c6 Linux 3.13-rc8) Merging arm-current/fixes (39544ac9df20 ARM: 7957/1: add DSB after icache flush in __flush_icache_all()) Merging m68k-current/for-linus (7247f55381d5 m68k: Wire up sched_setattr and sched_getattr) Merging metag-fixes/fixes (3b2f64d00c46 Linux 3.11-rc2) Merging powerpc-merge/merge (66f9af83e56b powerpc/eeh: Disable EEH on reboot) Merging sparc/master (738b52bb9845 Merge tag 'microblaze-3.14-rc3' of git://git.monstr.eu/linux-2.6-microblaze) Merging net/master (22f08ad9721d MAINTAINERS: add entry for the PHY library) Merging ipsec/master (738b52bb9845 Merge tag 'microblaze-3.14-rc3' of git://git.monstr.eu/linux-2.6-microblaze) Merging sound-current/for-linus (4913e0bf239d ALSA: hda - add headset mic detect quirks for two Dell laptops) Merging pci-current/for-linus (fc40363b2140 ahci: Fix broken fallback to single MSI mode) Merging wireless/master (4885c8731a34 hostap: fix "hostap: proc: Use remove_proc_subtree()") Merging driver-core.current/driver-core-linus (6d0abeca3242 Linux 3.14-rc3) Merging tty.current/tty-linus (6d0abeca3242 Linux 3.14-rc3) Merging usb.current/usb-linus (64fe1891696c phy: let phy_provider_register be the last step in registering PHY) Merging staging.current/staging-linus (6d0abeca3242 Linux 3.14-rc3) Merging char-misc.current/char-misc-linus (accb884b32e8 mei: set client's read_cb to NULL when flow control fails) Merging input-current/for-linus (70b0052425ff Input: da9052_onkey - use correct register bit for key status) Merging md-current/for-linus (d47648fcf061 raid5: avoid finding "discard" stripe) Merging crypto-current/master (ee97dc7db4cb crypto: s390 - fix des and des3_ede ctr concurrency issue) Merging ide/master (738b52bb9845 Merge tag 'microblaze-3.14-rc3' of git://git.monstr.eu/linux-2.6-microblaze) Merging dwmw2/master (5950f0803ca9 pcmcia: remove RPX board stuff) Merging devicetree-cur
Re: [RFC Patch v1 2/6] ACPI: rename acpi_evaluate_hotplug_ost to acpi_evaluate_ost for reuse
Hi Rafael, We have following code to deal with existing users. +#ifdef ACPI_HOTPLUG_OST +#defineacpi_evaluate_hotplug_ost acpi_evaluate_ost +#else +static inline acpi_status acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, - u32 status_code, struct acpi_buffer *status_buf); + u32 status_code, struct acpi_buffer *status_buf) +{ return AE_OK; } +#endif Thanks! On 2014/2/18 9:06, Rafael J. Wysocki wrote: > On Monday, February 17, 2014 01:02:49 PM Jiang Liu wrote: >> Rename acpi_evaluate_hotplug_ost() to acpi_evaluate_ost() for later resue. >> >> Signed-off-by: Jiang Liu >> --- >> drivers/acpi/utils.c| 14 -- >> include/acpi/acpi_bus.h | 10 +- >> 2 files changed, 13 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c >> index 85e3b61..19d0169 100644 >> --- a/drivers/acpi/utils.c >> +++ b/drivers/acpi/utils.c >> @@ -433,17 +433,15 @@ EXPORT_SYMBOL(acpi_get_physical_device_location); >> * When the platform does not support _OST, this function has no effect. >> */ >> acpi_status >> -acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, >> -u32 status_code, struct acpi_buffer *status_buf) > > There are users of this, what about updating them? > >> +acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, >> + struct acpi_buffer *status_buf) >> { >> -#ifdef ACPI_HOTPLUG_OST >> union acpi_object params[3] = { >> {.type = ACPI_TYPE_INTEGER,}, >> {.type = ACPI_TYPE_INTEGER,}, >> {.type = ACPI_TYPE_BUFFER,} >> }; >> struct acpi_object_list arg_list = {3, params}; >> -acpi_status status; >> >> params[0].integer.value = source_event; >> params[1].integer.value = status_code; >> @@ -455,13 +453,9 @@ acpi_evaluate_hotplug_ost(acpi_handle handle, u32 >> source_event, >> params[2].buffer.length = 0; >> } >> >> -status = acpi_evaluate_object(handle, "_OST", &arg_list, NULL); >> -return status; >> -#else >> -return AE_OK; >> -#endif >> +return acpi_evaluate_object(handle, "_OST", &arg_list, NULL); >> } >> -EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); >> +EXPORT_SYMBOL(acpi_evaluate_ost); >> >> /** >> * acpi_handle_printk: Print message with ACPI prefix and object path >> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h >> index 8256eb4..adef502 100644 >> --- a/include/acpi/acpi_bus.h >> +++ b/include/acpi/acpi_bus.h >> @@ -49,8 +49,16 @@ acpi_evaluate_reference(acpi_handle handle, >> struct acpi_object_list *arguments, >> struct acpi_handle_list *list); >> acpi_status >> +acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, >> + struct acpi_buffer *status_buf); >> +#ifdef ACPI_HOTPLUG_OST >> +#define acpi_evaluate_hotplug_ost acpi_evaluate_ost >> +#else >> +static inline acpi_status >> acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, >> -u32 status_code, struct acpi_buffer *status_buf); >> +u32 status_code, struct acpi_buffer *status_buf) >> +{ return AE_OK; } >> +#endif >> >> acpi_status >> acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info >> **pld); >> > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC Patch v1 1/6] acpi_pad: simplify notify handler by using acpi_drv_ops->notify
Thanks, Rafael. I will drop this patch then. On 2014/2/18 9:06, Rafael J. Wysocki wrote: > On Monday, February 17, 2014 01:02:48 PM Jiang Liu wrote: >> Use callback acpi_drv_ops->notify to simplify acpi_pad driver's >> notification handling code. >> >> Signed-off-by: Jiang Liu > > There is a plan to move away from using struct acpi_driver objects and > this change will need to be reverted then. I'm not sure if that's really > useful? > >> --- >> drivers/acpi/acpi_pad.c | 25 + >> 1 file changed, 5 insertions(+), 20 deletions(-) >> >> diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c >> index df96a0f..1e3ce76 100644 >> --- a/drivers/acpi/acpi_pad.c >> +++ b/drivers/acpi/acpi_pad.c >> @@ -443,14 +443,11 @@ static void acpi_pad_handle_notify(acpi_handle handle) >> mutex_unlock(&isolated_cpus_lock); >> } >> >> -static void acpi_pad_notify(acpi_handle handle, u32 event, >> -void *data) >> +static void acpi_pad_notify(struct acpi_device *device, u32 event) >> { >> -struct acpi_device *device = data; >> - >> switch (event) { >> case ACPI_PROCESSOR_AGGREGATOR_NOTIFY: >> -acpi_pad_handle_notify(handle); >> +acpi_pad_handle_notify(device->handle); >> acpi_bus_generate_netlink_event(device->pnp.device_class, >> dev_name(&device->dev), event, 0); >> break; >> @@ -462,22 +459,10 @@ static void acpi_pad_notify(acpi_handle handle, u32 >> event, >> >> static int acpi_pad_add(struct acpi_device *device) >> { >> -acpi_status status; >> - >> strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME); >> strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS); >> >> -if (acpi_pad_add_sysfs(device)) >> -return -ENODEV; >> - >> -status = acpi_install_notify_handler(device->handle, >> -ACPI_DEVICE_NOTIFY, acpi_pad_notify, device); >> -if (ACPI_FAILURE(status)) { >> -acpi_pad_remove_sysfs(device); >> -return -ENODEV; >> -} >> - >> -return 0; >> +return acpi_pad_add_sysfs(device); >> } >> >> static int acpi_pad_remove(struct acpi_device *device) >> @@ -486,9 +471,8 @@ static int acpi_pad_remove(struct acpi_device *device) >> acpi_pad_idle_cpus(0); >> mutex_unlock(&isolated_cpus_lock); >> >> -acpi_remove_notify_handler(device->handle, >> -ACPI_DEVICE_NOTIFY, acpi_pad_notify); >> acpi_pad_remove_sysfs(device); >> + >> return 0; >> } >> >> @@ -505,6 +489,7 @@ static struct acpi_driver acpi_pad_driver = { >> .ops = { >> .add = acpi_pad_add, >> .remove = acpi_pad_remove, >> +.notify = acpi_pad_notify, >> }, >> }; >> >> > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [GIT PULL 0/8] PHY subsystem fixes for 3.14-rc4
On Wednesday 19 February 2014 01:40 AM, Greg KH wrote: > On Mon, Feb 17, 2014 at 02:29:17PM +0530, Kishon Vijay Abraham I wrote: >> Hi Greg, >> >> Here's the PULL requeust for PHY subsystem for this -rc cycle. There isn't >> anything major but a bunch of obvious fixes and cleanup. >> >> Let me know If I have to change anything. >> >> Thanks >> Kishon >> >> The following changes since commit 6d0abeca3242a88cab8232e4acd7e2bf088f3bc2: >> >> Linux 3.14-rc3 (2014-02-16 13:30:25 -0800) >> >> are available in the git repository at: >> >> git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git >> tags/for-3.14-rc4 > > Is this a signed tag? It doesn't look like it from this side, so it > would be great if you could redo it as a signed tag so I "know" I'm > pulling the right thing in the future. ah.. sorry. Now changed that into a signed tag. Thanks Kishon -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/8] usb: phy: bcm-kona-usb2: Use PTR_ERR_OR_ZERO
On Wednesday 19 February 2014 01:41 AM, Greg KH wrote: > On Mon, Feb 17, 2014 at 02:29:20PM +0530, Kishon Vijay Abraham I wrote: >> From: Sachin Kamat >> >> PTR_ERR_OR_ZERO simplifies the code. >> >> Signed-off-by: Sachin Kamat >> Cc: Matt Porter >> Signed-off-by: Kishon Vijay Abraham I >> --- >> drivers/phy/phy-bcm-kona-usb2.c |4 +--- >> 1 file changed, 1 insertion(+), 3 deletions(-) >> >> diff --git a/drivers/phy/phy-bcm-kona-usb2.c >> b/drivers/phy/phy-bcm-kona-usb2.c >> index efc5c1a..e94f5a6 100644 >> --- a/drivers/phy/phy-bcm-kona-usb2.c >> +++ b/drivers/phy/phy-bcm-kona-usb2.c >> @@ -128,10 +128,8 @@ static int bcm_kona_usb2_probe(struct platform_device >> *pdev) >> >> phy_provider = devm_of_phy_provider_register(dev, >> of_phy_simple_xlate); >> -if (IS_ERR(phy_provider)) >> -return PTR_ERR(phy_provider); >> >> -return 0; >> +return PTR_ERR_OR_ZERO(phy_provider); >> } > > Another patch here that isn't a bugfix, sorry, it's not for 3.14-final. Ok. I'll have these patches for the next merge window. Thanks Kishon > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/2] asoc: soc-core: use regmap's parse_val to do endian translation
Update Liam and Mark's mail. On 02/19/2014 01:20 PM, Nenghua Cao wrote: > From: Nenghua Cao > > In snd_soc_bytes_put function, it forces cpu to do cpu_to_be translation, > but for mmio bus which uses REGMAP_ENDIAN_NATIVE, it doesn't need to do > endian translation. So it is better to use regmap's api which can decide > if this translation is needed according to bus configuration. > > Signed-off-by: Nenghua Cao > --- > sound/soc/soc-core.c | 34 +- > 1 files changed, 29 insertions(+), 5 deletions(-) > > diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c > index fe1df50..fb598cb 100644 > --- a/sound/soc/soc-core.c > +++ b/sound/soc/soc-core.c > @@ -3234,7 +3234,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, > struct soc_bytes *params = (void *)kcontrol->private_value; > struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); > int ret, len; > - unsigned int val; > + unsigned int val, mask; > void *data; > > if (!codec->using_regmap) > @@ -3264,12 +3264,36 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, > ((u8 *)data)[0] |= val; > break; > case 2: > - ((u16 *)data)[0] &= cpu_to_be16(~params->mask); > - ((u16 *)data)[0] |= cpu_to_be16(val); > + mask = ~params->mask; > + ret = regmap_parse_val(codec->control_data, > + &mask, &mask); > + if (ret != 0) > + goto out; > + > + ((u16 *)data)[0] &= mask; > + > + ret = regmap_parse_val(codec->control_data, > + &val, &val); > + if (ret != 0) > + goto out; > + > + ((u16 *)data)[0] |= val; > break; > case 4: > - ((u32 *)data)[0] &= cpu_to_be32(~params->mask); > - ((u32 *)data)[0] |= cpu_to_be32(val); > + mask = ~params->mask; > + ret = regmap_parse_val(codec->control_data, > + &mask, &mask); > + if (ret != 0) > + goto out; > + > + ((u32 *)data)[0] &= mask; > + > + ret = regmap_parse_val(codec->control_data, > + &val, &val); > + if (ret != 0) > + goto out; > + > + ((u32 *)data)[0] |= val; > break; > default: > ret = -EINVAL; > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] driver: regmap: add regmap_parse_val api
Update Liam and Mark's mail. On 02/19/2014 01:19 PM, Nenghua Cao wrote: > From: Nenghua Cao > > In some cases, we need regmap's format parse_val function > to do be/le translation according to the bus configuration. > For example, snd_soc_bytes_put() uses regmap to write/read values, > and use cpu_to_be() directly to covert MASK into big endian. This > is a defect, and should use regmap's format function to do it according > to bus configuration. > > Signed-off-by: Nenghua Cao > --- > drivers/base/regmap/regmap.c | 12 > include/linux/regmap.h |9 + > 2 files changed, 21 insertions(+), 0 deletions(-) > > diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c > index 6a19515..4b2ed0c 100644 > --- a/drivers/base/regmap/regmap.c > +++ b/drivers/base/regmap/regmap.c > @@ -2240,6 +2240,18 @@ int regmap_get_val_bytes(struct regmap *map) > } > EXPORT_SYMBOL_GPL(regmap_get_val_bytes); > > +int regmap_parse_val(struct regmap *map, const void *buf, > + unsigned int *val) > +{ > + if (!map->format.parse_val) > + return -EINVAL; > + > + *val = map->format.parse_val(buf); > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(regmap_parse_val); > + > static int __init regmap_initcall(void) > { > regmap_debugfs_initcall(); > diff --git a/include/linux/regmap.h b/include/linux/regmap.h > index 4149f1a..3e1a2e4 100644 > --- a/include/linux/regmap.h > +++ b/include/linux/regmap.h > @@ -423,6 +423,8 @@ bool regmap_check_range_table(struct regmap *map, > unsigned int reg, > > int regmap_register_patch(struct regmap *map, const struct reg_default *regs, > int num_regs); > +int regmap_parse_val(struct regmap *map, const void *buf, > + unsigned int *val); > > static inline bool regmap_reg_in_range(unsigned int reg, > const struct regmap_range *range) > @@ -695,6 +697,13 @@ static inline int regmap_register_patch(struct regmap > *map, > return -EINVAL; > } > > +static inline int regmap_parse_val(struct regmap *map, const void *buf, > + unsigned int *val) > +{ > + WARN_ONCE(1, "regmap API is disabled"); > + return -EINVAL; > +} > + > static inline struct regmap *dev_get_regmap(struct device *dev, > const char *name) > { > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
linux-next: build failure after merge of the final tree (sound-asoc tree related)
Hi all, After merging the final tree, today's linux-next build (powerpc allyesconfig) failed like this: sound/soc/intel/sst-dsp.c: In function 'sst_dsp_outbox_write': sound/soc/intel/sst-dsp.c:218:2: error: implicit declaration of function 'memcpy_toio' [-Werror=implicit-function-declaration] memcpy_toio(sst->mailbox.out_base, message, bytes); ^ sound/soc/intel/sst-dsp.c: In function 'sst_dsp_outbox_read': sound/soc/intel/sst-dsp.c:231:2: error: implicit declaration of function 'memcpy_fromio' [-Werror=implicit-function-declaration] memcpy_fromio(message, sst->mailbox.out_base, bytes); ^ Caused by commit 790aff62291e ("ASoC: Intel: Add Intel SST audio DSP low level shim driver") from the sound-asoc tree. I have disabled this new driver by reverting commit ddfa40b1586f ("ASoC: Intel: Add build support for Intel SST DSP core") for today. -- Cheers, Stephen Rothwells...@canb.auug.org.au pgpDtRddmmKP7.pgp Description: PGP signature
[PATCH 1/2] driver: regmap: add regmap_parse_val api
From: Nenghua Cao In some cases, we need regmap's format parse_val function to do be/le translation according to the bus configuration. For example, snd_soc_bytes_put() uses regmap to write/read values, and use cpu_to_be() directly to covert MASK into big endian. This is a defect, and should use regmap's format function to do it according to bus configuration. Signed-off-by: Nenghua Cao --- drivers/base/regmap/regmap.c | 12 include/linux/regmap.h |9 + 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 6a19515..4b2ed0c 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -2240,6 +2240,18 @@ int regmap_get_val_bytes(struct regmap *map) } EXPORT_SYMBOL_GPL(regmap_get_val_bytes); +int regmap_parse_val(struct regmap *map, const void *buf, + unsigned int *val) +{ + if (!map->format.parse_val) + return -EINVAL; + + *val = map->format.parse_val(buf); + + return 0; +} +EXPORT_SYMBOL_GPL(regmap_parse_val); + static int __init regmap_initcall(void) { regmap_debugfs_initcall(); diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 4149f1a..3e1a2e4 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -423,6 +423,8 @@ bool regmap_check_range_table(struct regmap *map, unsigned int reg, int regmap_register_patch(struct regmap *map, const struct reg_default *regs, int num_regs); +int regmap_parse_val(struct regmap *map, const void *buf, + unsigned int *val); static inline bool regmap_reg_in_range(unsigned int reg, const struct regmap_range *range) @@ -695,6 +697,13 @@ static inline int regmap_register_patch(struct regmap *map, return -EINVAL; } +static inline int regmap_parse_val(struct regmap *map, const void *buf, + unsigned int *val) +{ + WARN_ONCE(1, "regmap API is disabled"); + return -EINVAL; +} + static inline struct regmap *dev_get_regmap(struct device *dev, const char *name) { -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] sched: keep quiescent cpu out of idle balance loop
Since cpu which is put into quiescent mode, would remove itself from kernel's sched_domain. So we could use search sched_domain method to check whether this cpu don't want to be disturbed as idle load balance would send IPI to it. Signed-off-by: Lei Wen --- kernel/sched/fair.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 235cfa7..14230ae 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6783,6 +6783,8 @@ out_unlock: * - When one of the busy CPUs notice that there may be an idle rebalancing * needed, they will kick the idle load balancer, which then does idle * load balancing for all the idle CPUs. + * - exclude those cpus not inside current call_cpu's sched_domain, so that + * those isolated cpu could be kept in their quisecnt mode. */ static struct { cpumask_var_t idle_cpus_mask; @@ -6792,10 +6794,16 @@ static struct { static inline int find_new_ilb(void) { - int ilb = cpumask_first(nohz.idle_cpus_mask); + int ilb; + int cpu = smp_processor_id(); + struct sched_domain *tmp; - if (ilb < nr_cpu_ids && idle_cpu(ilb)) - return ilb; + for_each_domain(cpu, tmp) { + ilb = cpumask_first_and(nohz.idle_cpus_mask, + sched_domain_span(tmp)); + if (ilb < nr_cpu_ids && idle_cpu(ilb)) + return ilb; + } return nr_cpu_ids; } -- 1.8.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] asoc: soc-core: use regmap's parse_val to do endian translation
From: Nenghua Cao In snd_soc_bytes_put function, it forces cpu to do cpu_to_be translation, but for mmio bus which uses REGMAP_ENDIAN_NATIVE, it doesn't need to do endian translation. So it is better to use regmap's api which can decide if this translation is needed according to bus configuration. Signed-off-by: Nenghua Cao --- sound/soc/soc-core.c | 34 +- 1 files changed, 29 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index fe1df50..fb598cb 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3234,7 +3234,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, struct soc_bytes *params = (void *)kcontrol->private_value; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); int ret, len; - unsigned int val; + unsigned int val, mask; void *data; if (!codec->using_regmap) @@ -3264,12 +3264,36 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, ((u8 *)data)[0] |= val; break; case 2: - ((u16 *)data)[0] &= cpu_to_be16(~params->mask); - ((u16 *)data)[0] |= cpu_to_be16(val); + mask = ~params->mask; + ret = regmap_parse_val(codec->control_data, + &mask, &mask); + if (ret != 0) + goto out; + + ((u16 *)data)[0] &= mask; + + ret = regmap_parse_val(codec->control_data, + &val, &val); + if (ret != 0) + goto out; + + ((u16 *)data)[0] |= val; break; case 4: - ((u32 *)data)[0] &= cpu_to_be32(~params->mask); - ((u32 *)data)[0] |= cpu_to_be32(val); + mask = ~params->mask; + ret = regmap_parse_val(codec->control_data, + &mask, &mask); + if (ret != 0) + goto out; + + ((u32 *)data)[0] &= mask; + + ret = regmap_parse_val(codec->control_data, + &val, &val); + if (ret != 0) + goto out; + + ((u32 *)data)[0] |= val; break; default: ret = -EINVAL; -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] atm: solos-pci: make solos_bh() as static
>From 6297aabeff748777b520cc0ee835af0a3ddc79e2 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 19 Feb 2014 10:49:12 +0900 Subject: [PATCH] atm: solos-pci: make solos_bh() as static sparse says: drivers/atm/solos-pci.c:763:6: warning: symbol 'solos_bh' was not declared. Should it be static? Signed-off-by: Daeseok Youn --- drivers/atm/solos-pci.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index e3fb496..943cf0d 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -760,7 +760,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id) return IRQ_RETVAL(handled); } -void solos_bh(unsigned long card_arg) +static void solos_bh(unsigned long card_arg) { struct solos_card *card = (void *)card_arg; uint32_t card_flags; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] atm: nicstar: use NULL instead of 0 for pointer
>From c320d2ea1ed51c88255c33a50c74fa3598ab7be6 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 19 Feb 2014 10:10:11 +0900 Subject: [PATCH] atm: nicstar: use NULL instead of 0 for pointer sparse says: drivers/atm/nicstar.c:642:27: warning: Using plain integer as NULL pointer drivers/atm/nicstar.c:644:27: warning: Using plain integer as NULL pointer drivers/atm/nicstar.c:982:51: warning: Using plain integer as NULL pointer drivers/atm/nicstar.c:996:51: warning: Using plain integer as NULL pointer Signed-off-by: Daeseok Youn --- drivers/atm/nicstar.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 9587e95..13ed54c 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -639,9 +639,9 @@ static int ns_init_card(int i, struct pci_dev *pcidev) card->hbnr.init = NUM_HB; card->hbnr.max = MAX_HB; - card->sm_handle = 0x; + card->sm_handle = NULL; card->sm_addr = 0x; - card->lg_handle = 0x; + card->lg_handle = NULL; card->lg_addr = 0x; card->efbie = 1;/* To prevent push_rxbufs from enabling the interrupt */ @@ -979,7 +979,7 @@ static void push_rxbufs(ns_dev * card, struct sk_buff *skb) addr2 = card->sm_addr; handle2 = card->sm_handle; card->sm_addr = 0x; - card->sm_handle = 0x; + card->sm_handle = NULL; } else {/* (!sm_addr) */ card->sm_addr = addr1; @@ -993,7 +993,7 @@ static void push_rxbufs(ns_dev * card, struct sk_buff *skb) addr2 = card->lg_addr; handle2 = card->lg_handle; card->lg_addr = 0x; - card->lg_handle = 0x; + card->lg_handle = NULL; } else {/* (!lg_addr) */ card->lg_addr = addr1; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RESEND][PATCH v5 2/5] ACPI / processor_core: Rework _PDC related stuff to make it more arch-independent
_PDC related stuff in processor_core.c is little bit X86/IA64 dependent, macros of ACPI_PDC_* are _PDC bit definitions for Intel processors, if we use these macros in processor_core.c, we can not compile it when ACPI is enabled on ARM/ARM64. This patch reworks the code to make it more arch-independent, moving Intel related _PDC bits into architecture directory, no functional change. Cc: Tony Luck Cc: Fenghua Yu Cc: Thomas Gleixner Cc: "H. Peter Anvin" Cc: x...@kernel.org Cc: linux-i...@vger.kernel.org Signed-off-by: Hanjun Guo Signed-off-by: Graeme Gregory --- Hi Tony, Fenghua, Thomas, Peter, this patch was reviewed in ACPI mailling list, and updated for serveral versions, Rafael needs your opinion on this patch, could you please review and ack it? Thanks Hanjun --- arch/ia64/include/asm/acpi.h |5 + arch/ia64/kernel/acpi.c | 14 ++ arch/x86/include/asm/acpi.h | 19 +-- arch/x86/kernel/acpi/cstate.c | 29 + drivers/acpi/processor_core.c | 19 +-- 5 files changed, 46 insertions(+), 40 deletions(-) diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index d651102..d2b8b9d 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -152,10 +152,7 @@ extern int __initdata nid_to_pxm_map[MAX_NUMNODES]; #endif static inline bool arch_has_acpi_pdc(void) { return true; } -static inline void arch_acpi_set_pdc_bits(u32 *buf) -{ - buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; -} +extern void arch_acpi_set_pdc_bits(u32 *buf); #define acpi_unlazy_tlb(x) diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 07d209c..af9d9e4 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -1014,3 +1014,17 @@ EXPORT_SYMBOL(acpi_unregister_ioapic); * TBD when when IA64 starts to support suspend... */ int acpi_suspend_lowlevel(void) { return 0; } + +void arch_acpi_set_pdc_bits(u32 *buf) +{ + /* Enable coordination with firmware's _TSD info */ + buf[2] |= ACPI_PDC_SMP_T_SWCOORD | ACPI_PDC_EST_CAPABILITY_SMP; + if (boot_option_idle_override == IDLE_NOMWAIT) { + /* +* If mwait is disabled for CPU C-states, the C2C3_FFH access +* mode will be disabled in the parameter of _PDC object. +* Of course C1_FFH access mode will also be disabled. +*/ + buf[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); + } +} diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index c8c1e70..e9f71bc 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -147,24 +147,7 @@ static inline bool arch_has_acpi_pdc(void) c->x86_vendor == X86_VENDOR_CENTAUR); } -static inline void arch_acpi_set_pdc_bits(u32 *buf) -{ - struct cpuinfo_x86 *c = &cpu_data(0); - - buf[2] |= ACPI_PDC_C_CAPABILITY_SMP; - - if (cpu_has(c, X86_FEATURE_EST)) - buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; - - if (cpu_has(c, X86_FEATURE_ACPI)) - buf[2] |= ACPI_PDC_T_FFH; - - /* -* If mwait/monitor is unsupported, C2/C3_FFH will be disabled -*/ - if (!cpu_has(c, X86_FEATURE_MWAIT)) - buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); -} +extern void arch_acpi_set_pdc_bits(u32 *buf); #else /* !CONFIG_ACPI */ diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index e69182f..a36638f 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -16,6 +16,35 @@ #include #include +void arch_acpi_set_pdc_bits(u32 *buf) +{ + struct cpuinfo_x86 *c = &cpu_data(0); + + /* Enable coordination with firmware's _TSD info */ + buf[2] |= ACPI_PDC_SMP_T_SWCOORD | ACPI_PDC_C_CAPABILITY_SMP; + + if (cpu_has(c, X86_FEATURE_EST)) + buf[2] |= ACPI_PDC_EST_CAPABILITY_SWSMP; + + if (cpu_has(c, X86_FEATURE_ACPI)) + buf[2] |= ACPI_PDC_T_FFH; + + /* +* If mwait/monitor is unsupported, C2/C3_FFH will be disabled +*/ + if (!cpu_has(c, X86_FEATURE_MWAIT)) + buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); + + if (boot_option_idle_override == IDLE_NOMWAIT) { + /* +* If mwait is disabled for CPU C-states, the C2C3_FFH access +* mode will be disabled in the parameter of _PDC object. +* Of course C1_FFH access mode will also be disabled. +*/ + buf[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); + } +} + /* * Initialize bm_flags based on the CPU cache properties * On SMP it depends on cache configuration diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 4d91b32..4dcf776 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -255,9 +255,6 @@ static void acpi_set_pdc_bits(u32 *buf) buf[0] =
[PATCH] atm: ambassador: use NULL instead of 0 for pointer
>From 932e928d53b1e588dc17019e7f9fa7a61b8b7468 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 19 Feb 2014 10:35:41 +0900 Subject: [PATCH] atm: ambassador: use NULL instead of 0 for pointer sparse says: drivers/atm/ambassador.c:1928:24: warning: Using plain integer as NULL pointer Signed-off-by: Daeseok Youn --- drivers/atm/ambassador.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index 62a7607..f1a9198 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c @@ -1925,7 +1925,7 @@ static int ucode_init(loader_block *lb, amb_dev *dev) const struct firmware *fw; unsigned long start_address; const struct ihex_binrec *rec; - const char *errmsg = 0; + const char *errmsg = NULL; int res; res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev); -- 1.7.9.5 --- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/