Rebase to Linux 3.3-rc1
The utrace patch is left unapplied as it doesn't apply cleanly any longer
This commit is contained in:
parent
0a621ccdd4
commit
e8409b1dce
@ -1,42 +0,0 @@
|
||||
From c0190925dacd976a67044f4382d4effbed568dce Mon Sep 17 00:00:00 2001
|
||||
From: Jesse Sung <jesse.sung@canonical.com>
|
||||
Date: Thu, 22 Dec 2011 10:48:47 +0800
|
||||
Subject: [PATCH] Bluetooth: Add support for BCM20702A0 [0a5c:21e3]
|
||||
|
||||
Add another vendor specific ID for BCM20702A0.
|
||||
|
||||
output of usb-devices:
|
||||
T: Bus=06 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 4 Spd=12 MxCh= 0
|
||||
D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
|
||||
P: Vendor=0a5c ProdID=21e3 Rev=01.12
|
||||
S: Manufacturer=Broadcom Corp
|
||||
S: Product=BCM20702A0
|
||||
S: SerialNumber=9439E5CBF66C
|
||||
C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA
|
||||
I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
|
||||
I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
|
||||
I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
|
||||
I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)
|
||||
|
||||
Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com>
|
||||
Acked-by: Marcel Holtmann <marcel@holtmann.org>
|
||||
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
|
||||
---
|
||||
drivers/bluetooth/btusb.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
||||
index a67c6db..fbfba80 100644
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -101,6 +101,7 @@ static struct usb_device_id btusb_table[] = {
|
||||
{ USB_DEVICE(0x0c10, 0x0000) },
|
||||
|
||||
/* Broadcom BCM20702A0 */
|
||||
+ { USB_DEVICE(0x0a5c, 0x21e3) },
|
||||
{ USB_DEVICE(0x413c, 0x8197) },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
--
|
||||
1.7.6.2
|
||||
|
@ -7,15 +7,7 @@
|
||||
|
||||
**** Queued for 3.3 ***********************************************************************************
|
||||
drm-edid-try-harder-to-fix-up-broken-headers.patch
|
||||
Bluetooth-Add-support-for-BCM20702A0-0a5c-21e3.patch
|
||||
ext4-Support-check-none-nocheck-mount-options.patch
|
||||
ext4-Fix-error-handling-on-inode-bitmap-corruption.patch
|
||||
proc-clean-up-and-fix-proc-pid-mem-handling.patch
|
||||
proc-fix-null-pointer-deref-in-proc_pid_permission.patch
|
||||
procfs-add-hidepid-and-gid-mount-options.patch
|
||||
procfs-parse-mount-options.patch
|
||||
epoll-limit-paths.patch
|
||||
Unused-iocbs-in-a-batch-should-not-be-accounted-as-a.patch
|
||||
|
||||
**** Other stuff that should go upstream (in decreasing likelyhood) ************************************
|
||||
|
||||
|
@ -1,68 +0,0 @@
|
||||
From 69e4747ee9727d660b88d7e1efe0f4afcb35db1b Mon Sep 17 00:00:00 2001
|
||||
From: Gleb Natapov <gleb@redhat.com>
|
||||
Date: Sun, 8 Jan 2012 17:07:28 +0200
|
||||
Subject: [PATCH] Unused iocbs in a batch should not be accounted as active.
|
||||
|
||||
Since commit 080d676de095 ("aio: allocate kiocbs in batches") iocbs are
|
||||
allocated in a batch during processing of first iocbs. All iocbs in a
|
||||
batch are automatically added to ctx->active_reqs list and accounted in
|
||||
ctx->reqs_active.
|
||||
|
||||
If one (not the last one) of iocbs submitted by an user fails, further
|
||||
iocbs are not processed, but they are still present in ctx->active_reqs
|
||||
and accounted in ctx->reqs_active. This causes process to stuck in a D
|
||||
state in wait_for_all_aios() on exit since ctx->reqs_active will never
|
||||
go down to zero. Furthermore since kiocb_batch_free() frees iocb
|
||||
without removing it from active_reqs list the list become corrupted
|
||||
which may cause oops.
|
||||
|
||||
Fix this by removing iocb from ctx->active_reqs and updating
|
||||
ctx->reqs_active in kiocb_batch_free().
|
||||
|
||||
Signed-off-by: Gleb Natapov <gleb@redhat.com>
|
||||
Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
|
||||
Cc: stable@kernel.org # 3.2
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
fs/aio.c | 11 +++++++++--
|
||||
1 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/aio.c b/fs/aio.c
|
||||
index 78c514c..969beb0 100644
|
||||
--- a/fs/aio.c
|
||||
+++ b/fs/aio.c
|
||||
@@ -476,14 +476,21 @@ static void kiocb_batch_init(struct kiocb_batch *batch, long total)
|
||||
batch->count = total;
|
||||
}
|
||||
|
||||
-static void kiocb_batch_free(struct kiocb_batch *batch)
|
||||
+static void kiocb_batch_free(struct kioctx *ctx, struct kiocb_batch *batch)
|
||||
{
|
||||
struct kiocb *req, *n;
|
||||
|
||||
+ if (list_empty(&batch->head))
|
||||
+ return;
|
||||
+
|
||||
+ spin_lock_irq(&ctx->ctx_lock);
|
||||
list_for_each_entry_safe(req, n, &batch->head, ki_batch) {
|
||||
list_del(&req->ki_batch);
|
||||
+ list_del(&req->ki_list);
|
||||
kmem_cache_free(kiocb_cachep, req);
|
||||
+ ctx->reqs_active--;
|
||||
}
|
||||
+ spin_unlock_irq(&ctx->ctx_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1742,7 +1749,7 @@ long do_io_submit(aio_context_t ctx_id, long nr,
|
||||
}
|
||||
blk_finish_plug(&plug);
|
||||
|
||||
- kiocb_batch_free(&batch);
|
||||
+ kiocb_batch_free(ctx, &batch);
|
||||
put_ioctx(ctx);
|
||||
return i ? i : ret;
|
||||
}
|
||||
--
|
||||
1.7.7.5
|
||||
|
1861
alps.patch
1861
alps.patch
File diff suppressed because it is too large
Load Diff
@ -22,14 +22,15 @@ diff -up linux-3.1.x86_64/drivers/bcma/host_pci.c.orig linux-3.1.x86_64/drivers/
|
||||
{ 0, },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
|
||||
diff -up linux-3.1.x86_64/drivers/net/wireless/brcm80211/Kconfig.orig linux-3.1.x86_64/drivers/net/wireless/brcm80211/Kconfig
|
||||
--- linux-3.1.x86_64/drivers/net/wireless/brcm80211/Kconfig.orig 2011-11-10 11:42:31.764930961 -0500
|
||||
+++ linux-3.1.x86_64/drivers/net/wireless/brcm80211/Kconfig 2011-11-10 11:42:33.613907846 -0500
|
||||
@@ -5,7 +5,6 @@ config BRCMSMAC
|
||||
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
|
||||
index cd6375d..caa0302 100644
|
||||
--- a/drivers/net/wireless/brcm80211/Kconfig
|
||||
+++ b/drivers/net/wireless/brcm80211/Kconfig
|
||||
@@ -4,7 +4,6 @@ config BRCMUTIL
|
||||
config BRCMSMAC
|
||||
tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
|
||||
depends on PCI
|
||||
depends on MAC80211
|
||||
- depends on BCMA=n
|
||||
- depends on BCMA
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
select CRC_CCITT
|
||||
|
@ -1,131 +0,0 @@
|
||||
--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
|
||||
+++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
|
||||
@@ -265,7 +265,6 @@ int rtl92c_download_fw(struct ieee80211_
|
||||
if (!rtlhal->pfirmware)
|
||||
return 1;
|
||||
|
||||
- pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
|
||||
pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
|
||||
pfwdata = (u8 *) rtlhal->pfirmware;
|
||||
fwsize = rtlhal->fwsize;
|
||||
--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
|
||||
+++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
|
||||
@@ -186,6 +186,7 @@ int rtl92c_init_sw_vars(struct ieee80211
|
||||
memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
|
||||
rtlpriv->rtlhal.fwsize = firmware->size;
|
||||
release_firmware(firmware);
|
||||
+ pr_info("rtl8192ce: Loaded firmware file %s\n", rtlpriv->cfg->fw_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
|
||||
+++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
|
||||
@@ -43,6 +43,8 @@
|
||||
#include "hw.h"
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/atomic.h>
|
||||
+#include <linux/types.h>
|
||||
|
||||
MODULE_AUTHOR("Georgia <georgia@realtek.com>");
|
||||
MODULE_AUTHOR("Ziv Huang <ziv_huang@realtek.com>");
|
||||
@@ -51,6 +53,10 @@ MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");
|
||||
MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
|
||||
|
||||
+static char *rtl8192cu_firmware; /* pointer to firmware */
|
||||
+static int firmware_size;
|
||||
+static atomic_t usage_count;
|
||||
+
|
||||
static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
@@ -62,12 +68,21 @@ static int rtl92cu_init_sw_vars(struct i
|
||||
rtlpriv->dm.disable_framebursting = false;
|
||||
rtlpriv->dm.thermalvalue = 0;
|
||||
rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
|
||||
- rtlpriv->rtlhal.pfirmware = vmalloc(0x4000);
|
||||
- if (!rtlpriv->rtlhal.pfirmware) {
|
||||
+
|
||||
+ if (rtl8192cu_firmware) {
|
||||
+ /* firmware already loaded - true for suspend/resume
|
||||
+ * and multiple instances of the device */
|
||||
+ rtlpriv->rtlhal.pfirmware = rtl8192cu_firmware;
|
||||
+ rtlpriv->rtlhal.fwsize = firmware_size;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ rtl8192cu_firmware = vzalloc(0x4000);
|
||||
+ if (!rtl8192cu_firmware) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Can't alloc buffer for fw.\n"));
|
||||
return 1;
|
||||
}
|
||||
+
|
||||
/* request fw */
|
||||
err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
|
||||
rtlpriv->io.dev);
|
||||
@@ -82,9 +97,14 @@ static int rtl92cu_init_sw_vars(struct i
|
||||
release_firmware(firmware);
|
||||
return 1;
|
||||
}
|
||||
- memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
|
||||
+ pr_info("rtl8192cu: Loaded firmware from file %s\n",
|
||||
+ rtlpriv->cfg->fw_name);
|
||||
+ memcpy(rtl8192cu_firmware, firmware->data, firmware->size);
|
||||
+ firmware_size = firmware->size;
|
||||
rtlpriv->rtlhal.fwsize = firmware->size;
|
||||
+ rtlpriv->rtlhal.pfirmware = rtl8192cu_firmware;
|
||||
release_firmware(firmware);
|
||||
+ atomic_inc(&usage_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -93,12 +113,30 @@ static void rtl92cu_deinit_sw_vars(struc
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
- if (rtlpriv->rtlhal.pfirmware) {
|
||||
- vfree(rtlpriv->rtlhal.pfirmware);
|
||||
+ atomic_dec(&usage_count);
|
||||
+ if (!atomic_read(&usage_count) && rtlpriv->rtlhal.pfirmware) {
|
||||
+ vfree(rtl8192cu_firmware);
|
||||
+ rtl8192cu_firmware = NULL;
|
||||
rtlpriv->rtlhal.pfirmware = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+static int rtl8192cu_usb_suspend(struct usb_interface *pusb_intf,
|
||||
+ pm_message_t message)
|
||||
+{
|
||||
+ /* Increase usage_count to Save loaded fw across suspend/resume */
|
||||
+ atomic_inc(&usage_count);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rtl8192cu_usb_resume(struct usb_interface *pusb_intf)
|
||||
+{
|
||||
+ atomic_dec(&usage_count); /* after resume, decrease usage count */
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static struct rtl_hal_ops rtl8192cu_hal_ops = {
|
||||
.init_sw_vars = rtl92cu_init_sw_vars,
|
||||
.deinit_sw_vars = rtl92cu_deinit_sw_vars,
|
||||
@@ -374,11 +412,10 @@ static struct usb_driver rtl8192cu_drive
|
||||
.disconnect = rtl_usb_disconnect,
|
||||
.id_table = rtl8192c_usb_ids,
|
||||
|
||||
-#ifdef CONFIG_PM
|
||||
- /* .suspend = rtl_usb_suspend, */
|
||||
- /* .resume = rtl_usb_resume, */
|
||||
- /* .reset_resume = rtl8192c_resume, */
|
||||
-#endif /* CONFIG_PM */
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+ .suspend = rtl8192cu_usb_suspend,
|
||||
+ .resume = rtl8192cu_usb_resume,
|
||||
+#endif /* CONFIG_PM_SLEEP */
|
||||
#ifdef CONFIG_AUTOSUSPEND
|
||||
.supports_autosuspend = 1,
|
||||
#endif
|
@ -200,3 +200,4 @@ CONFIG_ARM_ERRATA_751472=y
|
||||
# CONFIG_NET_VENDOR_CIRRUS is not set
|
||||
# CONFIG_CS89x0 is not set
|
||||
|
||||
# CONFIG_OF_SELFTEST is not set
|
||||
|
@ -96,3 +96,9 @@ CONFIG_CPU_FREQ_STAT_DETAILS=y
|
||||
|
||||
CONFIG_PL310_ERRATA_769419=y
|
||||
CONFIG_LEDS_RENESAS_TPU=y
|
||||
|
||||
# CONFIG_ARM_LPAE is not set
|
||||
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
|
||||
# CONFIG_INPUT_GP2A is not set
|
||||
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
|
||||
|
||||
|
@ -40,3 +40,7 @@ CONFIG_RTC_DRV_MV=m
|
||||
CONFIG_MV_XOR=y
|
||||
CONFIG_CRYPTO_DEV_MV_CESA=m
|
||||
|
||||
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
|
||||
# CONFIG_INPUT_GP2A is not set
|
||||
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
|
||||
|
||||
|
@ -1083,3 +1083,19 @@ CONFIG_LEDS_RENESAS_TPU=y
|
||||
# CONFIG_OMAP_IOMMU is not set
|
||||
CONFIG_USB_RENESAS_USBHS_HCD=m
|
||||
|
||||
# CONFIG_ARM_LPAE is not set
|
||||
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
|
||||
# CONFIG_INPUT_GP2A is not set
|
||||
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
|
||||
# CONFIG_SOC_OMAPTI81XX is not set
|
||||
# CONFIG_SOC_OMAPAM33XX is not set
|
||||
# CONFIG_MACH_TI8148EVM is not set
|
||||
# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
|
||||
# CONFIG_MICREL_KS8995MA is not set
|
||||
# CONFIG_CHARGER_MANAGER is not set
|
||||
# CONFIG_MFD_DA9052_SPI is not set
|
||||
# CONFIG_MFD_DA9052_I2C is not set
|
||||
# CONFIG_MFD_S5M_CORE is not set
|
||||
# CONFIG_VIDEO_AS3645A is not set
|
||||
#
|
||||
|
||||
|
@ -90,3 +90,15 @@ CONFIG_ARM_CPU_TOPOLOGY=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_SCHED_SMT=y
|
||||
CONFIG_LEDS_RENESAS_TPU=y
|
||||
|
||||
# CONFIG_ARCH_TEGRA_2x_SOC is not set
|
||||
# CONFIG_ARCH_TEGRA_3x_SOC is not set
|
||||
# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set
|
||||
# CONFIG_ETHERNET is not set
|
||||
# CONFIG_NET_VENDOR_BROADCOM is not set
|
||||
# CONFIG_INPUT_GP2A is not set
|
||||
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
|
||||
# CONFIG_DVB_TDA1004X is not set
|
||||
# CONFIG_DVB_PLL is not set
|
||||
# CONFIG_SND_SOC_TEGRA_ALC5632 is not set
|
||||
|
||||
|
@ -149,6 +149,7 @@ CONFIG_INFINIBAND_IPOIB_DEBUG=y
|
||||
CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
|
||||
CONFIG_INFINIBAND_IPOIB_CM=y
|
||||
CONFIG_INFINIBAND_SRP=m
|
||||
CONFIG_INFINIBAND_SRPT=m
|
||||
CONFIG_INFINIBAND_USER_MAD=m
|
||||
CONFIG_INFINIBAND_USER_ACCESS=m
|
||||
CONFIG_INFINIBAND_IPATH=m
|
||||
@ -248,6 +249,7 @@ CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
|
||||
CONFIG_BLK_DEV_CRYPTOLOOP=m
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_NVME=m
|
||||
CONFIG_BLK_DEV_OSD=m
|
||||
CONFIG_BLK_DEV_RAM=m
|
||||
CONFIG_BLK_DEV_RAM_COUNT=16
|
||||
@ -648,12 +650,14 @@ CONFIG_TCP_MD5SIG=y
|
||||
#
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_UNIX_DIAG=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_NET_KEY_MIGRATE=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_INET_LRO=y
|
||||
CONFIG_INET_TUNNEL=m
|
||||
CONFIG_INET_DIAG=m
|
||||
CONFIG_INET_UDP_DIAG=m
|
||||
CONFIG_IP_MULTICAST=y
|
||||
CONFIG_IP_ADVANCED_ROUTER=y
|
||||
CONFIG_IP_FIB_TRIE_STATS=y
|
||||
@ -702,6 +706,12 @@ CONFIG_IP_VS_DH=m
|
||||
CONFIG_IP_VS_SH=m
|
||||
CONFIG_IP_VS_SED=m
|
||||
CONFIG_IP_VS_NQ=m
|
||||
|
||||
#
|
||||
# IPVS SH scheduler
|
||||
#
|
||||
CONFIG_IP_VS_SH_TAB_BITS=8
|
||||
|
||||
CONFIG_IP_VS_FTP=m
|
||||
CONFIG_IP_VS_PE_SIP=m
|
||||
|
||||
@ -744,6 +754,7 @@ CONFIG_NETFILTER=y
|
||||
CONFIG_NETFILTER_ADVANCED=y
|
||||
CONFIG_NF_CONNTRACK=m
|
||||
CONFIG_NETFILTER_NETLINK=m
|
||||
CONFIG_NETFILTER_NETLINK_ACCT=m
|
||||
CONFIG_NETFILTER_NETLINK_QUEUE=m
|
||||
CONFIG_NETFILTER_NETLINK_LOG=m
|
||||
CONFIG_NETFILTER_TPROXY=m
|
||||
@ -784,6 +795,7 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_MATCH_DCCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_DSCP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ECN=m
|
||||
CONFIG_NETFILTER_XT_MATCH_ESP=m
|
||||
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_HELPER=m
|
||||
@ -795,6 +807,7 @@ CONFIG_NETFILTER_XT_MATCH_LIMIT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MAC=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MARK=m
|
||||
CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_NFACCT=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OSF=m
|
||||
CONFIG_NETFILTER_XT_MATCH_OWNER=m
|
||||
CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
|
||||
@ -824,6 +837,7 @@ CONFIG_NF_CONNTRACK_MARK=y
|
||||
CONFIG_NF_CONNTRACK_SECMARK=y
|
||||
CONFIG_NF_CONNTRACK_EVENTS=y
|
||||
CONFIG_NF_CONNTRACK_ZONES=y
|
||||
CONFIG_NF_CONNTRACK_PROCFS=y # check if contrack(8) in f17 supports netlink
|
||||
# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
|
||||
CONFIG_NF_CONNTRACK_AMANDA=m
|
||||
CONFIG_NF_CONNTRACK_FTP=m
|
||||
@ -847,6 +861,7 @@ CONFIG_NF_CT_PROTO_UDPLITE=m
|
||||
|
||||
CONFIG_IP_NF_MATCH_AH=m
|
||||
CONFIG_IP_NF_MATCH_ECN=m
|
||||
CONFIG_IP_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP_NF_MATCH_TTL=m
|
||||
CONFIG_IP_NF_TARGET_CLUSTERIP=m
|
||||
CONFIG_IP_NF_TARGET_MASQUERADE=m
|
||||
@ -879,6 +894,7 @@ CONFIG_IP6_NF_MATCH_FRAG=m
|
||||
CONFIG_IP6_NF_MATCH_HL=m
|
||||
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
|
||||
CONFIG_IP6_NF_MATCH_MH=m
|
||||
CONFIG_IP6_NF_MATCH_RPFILTER=m
|
||||
CONFIG_IP6_NF_MATCH_OPTS=m
|
||||
CONFIG_IP6_NF_MATCH_RT=m
|
||||
CONFIG_IP6_NF_QUEUE=m
|
||||
@ -1040,6 +1056,9 @@ CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
|
||||
CONFIG_DCB=y
|
||||
# CONFIG_OPENVSWITCH is not set
|
||||
CONFIG_NETPRIO_CGROUP=m
|
||||
|
||||
|
||||
#
|
||||
# Network testing
|
||||
@ -1056,6 +1075,9 @@ CONFIG_NETDEVICES=y
|
||||
#
|
||||
# CONFIG_ARCNET is not set
|
||||
CONFIG_IFB=m
|
||||
CONFIG_NET_TEAM=m
|
||||
CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
|
||||
CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
|
||||
CONFIG_DUMMY=m
|
||||
CONFIG_BONDING=m
|
||||
CONFIG_MACVLAN=m
|
||||
@ -1143,6 +1165,7 @@ CONFIG_ATL1E=m
|
||||
|
||||
CONFIG_NET_VENDOR_BROCADE=y
|
||||
CONFIG_BNA=m
|
||||
CONFIG_NET_CALXEDA_XGMAC=m
|
||||
|
||||
CONFIG_NET_VENDOR_CHELSIO=y
|
||||
CONFIG_CHELSIO_T1=m
|
||||
@ -1275,6 +1298,8 @@ CONFIG_SMSC9420=m
|
||||
|
||||
CONFIG_NET_VENDOR_STMICRO=y
|
||||
CONFIG_STMMAC_ETH=m
|
||||
# CONFIG_STMMAC_PLATFORM is not set
|
||||
# CONFIG_STMMAC_PCI is not set
|
||||
# CONFIG_STMMAC_DA is not set
|
||||
# CONFIG_STMMAC_DUAL_MAC is not set
|
||||
# CONFIG_STMMAC_TIMER is not set
|
||||
@ -1424,6 +1449,7 @@ CONFIG_ATH9K_AHB=y
|
||||
# CONFIG_ATH9K_DEBUG is not set
|
||||
CONFIG_ATH9K_DEBUGFS=y
|
||||
CONFIG_ATH9K_HTC=m
|
||||
CONFIG_ATH9K_BTCOEX_SUPPORT=y
|
||||
# CONFIG_ATH9K_HTC_DEBUGFS is not set
|
||||
CONFIG_ATH9K_RATE_CONTROL=y
|
||||
CONFIG_CARL9170=m
|
||||
@ -1452,6 +1478,7 @@ CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
|
||||
# CONFIG_B43LEGACY_PIO_MODE is not set
|
||||
CONFIG_BRCMSMAC=m
|
||||
CONFIG_BRCMFMAC=m
|
||||
CONFIG_BRCMFMAC_SDIO=y
|
||||
# CONFIG_BRCMDBG is not set
|
||||
CONFIG_HERMES=m
|
||||
CONFIG_HERMES_CACHE_FW_ON_INIT=y
|
||||
@ -1485,11 +1512,10 @@ CONFIG_IWLWIFI=m
|
||||
CONFIG_IWLWIFI_DEBUG=y
|
||||
CONFIG_IWLWIFI_DEBUGFS=y
|
||||
CONFIG_IWLWIFI_DEVICE_SVTOOL=y
|
||||
# CONFIG_IWL_P2P is not set
|
||||
CONFIG_IWLAGN=m
|
||||
CONFIG_IWLWIFI_LEGACY=m
|
||||
CONFIG_IWLWIFI_LEGACY_DEBUG=y
|
||||
CONFIG_IWLWIFI_LEGACY_DEBUGFS=y
|
||||
# CONFIG_IWLWIFI_P2P is not set
|
||||
CONFIG_IWLEGACY=m
|
||||
CONFIG_IWLEGACY_DEBUG=y
|
||||
CONFIG_IWLEGACY_DEBUGFS=y
|
||||
# CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING is not set
|
||||
CONFIG_IWL4965=y
|
||||
CONFIG_IWL3945=m
|
||||
@ -1869,8 +1895,10 @@ CONFIG_KEYBOARD_ATKBD=y
|
||||
# CONFIG_KEYBOARD_QT1070 is not set
|
||||
# CONFIG_KEYBOARD_MCS is not set
|
||||
# CONFIG_KEYBOARD_OPENCORES is not set
|
||||
# CONFIG_KEYBOARD_SAMSUNG is not set
|
||||
# CONFIG_KEYBOARD_QT2160 is not set
|
||||
# CONFIG_KEYBOARD_TCA6416 is not set
|
||||
# CONFIG_KEYBOARD_TCA8418 is not set
|
||||
CONFIG_INPUT_MOUSE=y
|
||||
CONFIG_MOUSE_PS2=y
|
||||
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
|
||||
@ -1919,6 +1947,7 @@ CONFIG_TOUCHSCREEN_AD7879_I2C=m
|
||||
# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
|
||||
CONFIG_TOUCHSCREEN_DYNAPRO=m
|
||||
CONFIG_TOUCHSCREEN_EETI=m
|
||||
CONFIG_TOUCHSCREEN_EGALAX=m
|
||||
CONFIG_TOUCHSCREEN_ELO=m
|
||||
CONFIG_TOUCHSCREEN_FUJITSU=m
|
||||
CONFIG_TOUCHSCREEN_GUNZE=m
|
||||
@ -1934,6 +1963,7 @@ CONFIG_TOUCHSCREEN_TSC2007=m
|
||||
CONFIG_TOUCHSCREEN_TOUCHIT213=m
|
||||
CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
|
||||
CONFIG_TOUCHSCREEN_TOUCHWIN=m
|
||||
CONFIG_TOUCHSCREEN_PIXCIR=m
|
||||
CONFIG_TOUCHSCREEN_UCB1400=m
|
||||
CONFIG_TOUCHSCREEN_WACOM_W8001=m
|
||||
CONFIG_TOUCHSCREEN_USB_E2I=y
|
||||
@ -2421,6 +2451,7 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y
|
||||
#
|
||||
CONFIG_V4L_USB_DRIVERS=y
|
||||
CONFIG_VIDEO_CAPTURE_DRIVERS=y
|
||||
CONFIG_V4L_PCI_DRIVERS=y
|
||||
CONFIG_VIDEO_AU0828=m
|
||||
CONFIG_VIDEO_BT848=m
|
||||
CONFIG_VIDEO_BT848_DVB=y
|
||||
@ -2471,6 +2502,8 @@ CONFIG_VIDEO_ZORAN_DC30=m
|
||||
CONFIG_VIDEO_ZORAN_LML33=m
|
||||
CONFIG_VIDEO_ZORAN_LML33R10=m
|
||||
CONFIG_VIDEO_ZORAN_ZR36060=m
|
||||
# CONFIG_V4L_ISA_PARPORT_DRIVERS is not set
|
||||
# CONFIG_V4L_PLATFORM_DRIVERS is not set
|
||||
CONFIG_VIDEO_FB_IVTV=m
|
||||
CONFIG_VIDEO_SAA7164=m
|
||||
CONFIG_VIDEO_TM6000=m
|
||||
@ -2498,6 +2531,7 @@ CONFIG_MEDIA_TUNER_TEA5761=m
|
||||
CONFIG_MEDIA_TUNER_TEA5767=m
|
||||
CONFIG_MEDIA_TUNER_MT20XX=m
|
||||
CONFIG_MEDIA_TUNER_MT2060=m
|
||||
CONFIG_MEDIA_TUNER_MT2063=m
|
||||
CONFIG_MEDIA_TUNER_MT2266=m
|
||||
CONFIG_MEDIA_TUNER_MT2131=m
|
||||
CONFIG_MEDIA_TUNER_QT1010=m
|
||||
@ -2621,6 +2655,7 @@ CONFIG_DVB_DDBRIDGE=m
|
||||
CONFIG_DVB_MB86A20S=m
|
||||
CONFIG_DVB_USB_TECHNISAT_USB2=m
|
||||
CONFIG_DVB_DIB9000=m
|
||||
CONFIG_DVB_HD29L2=m
|
||||
CONFIG_DVB_STV0367=m
|
||||
|
||||
#
|
||||
@ -2696,6 +2731,7 @@ CONFIG_IR_RC6_DECODER=m
|
||||
CONFIG_IR_JVC_DECODER=m
|
||||
CONFIG_IR_SONY_DECODER=m
|
||||
CONFIG_IR_RC5_SZ_DECODER=m
|
||||
CONFIG_IR_SANYO_DECODER=m
|
||||
CONFIG_IR_MCE_KBD_DECODER=m
|
||||
CONFIG_IR_LIRC_CODEC=m
|
||||
CONFIG_IR_IMON=m
|
||||
@ -2996,6 +3032,7 @@ CONFIG_USB_SUSPEND=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_ROOT_HUB_TT=y
|
||||
CONFIG_USB_EHCI_TT_NEWSCHED=y
|
||||
# CONFIG_USB_EHCI_MV is not set
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
# CONFIG_USB_OHCI_HCD_SSB is not set
|
||||
CONFIG_USB_UHCI_HCD=y
|
||||
@ -3101,11 +3138,13 @@ CONFIG_HID_ACRUX_FF=y
|
||||
CONFIG_HID_KEYTOUCH=m
|
||||
CONFIG_HID_LCPOWER=m
|
||||
CONFIG_HID_ROCCAT_ARVO=m
|
||||
CONFIG_HID_ROCCAT_ISKU=m
|
||||
CONFIG_HID_ROCCAT_KOVAPLUS=m
|
||||
CONFIG_HID_HOLTEK=m
|
||||
CONFIG_HOLTEK_FF=y
|
||||
CONFIG_HID_SPEEDLINK=m
|
||||
CONFIG_HID_WIIMOTE=m
|
||||
CONFIG_HID_WIIMOTE_EXT=y
|
||||
|
||||
#
|
||||
# USB Imaging devices
|
||||
@ -3157,6 +3196,7 @@ CONFIG_USB_GSPCA_PAC7302=m
|
||||
CONFIG_USB_GSPCA_STV0680=m
|
||||
CONFIG_USB_GL860=m
|
||||
CONFIG_USB_GSPCA_JEILINJ=m
|
||||
CONFIG_USB_GSPCA_JL2005BCD=m
|
||||
CONFIG_USB_GSPCA_KONICA=m
|
||||
CONFIG_USB_GSPCA_XIRLINK_CIT=m
|
||||
CONFIG_USB_GSPCA_SPCA1528=m
|
||||
@ -3547,6 +3587,8 @@ CONFIG_NFSD=m
|
||||
CONFIG_NFSD_V3=y
|
||||
CONFIG_NFSD_V3_ACL=y
|
||||
CONFIG_NFSD_V4=y
|
||||
# Maybe see if we want this on for debug kernels?
|
||||
# CONFIG_NFSD_FAULT_INJECTION is not set
|
||||
CONFIG_NFS_FSCACHE=y
|
||||
# CONFIG_NFS_USE_LEGACY_DNS is not set
|
||||
CONFIG_NFS_USE_NEW_IDMAPPER=y
|
||||
@ -3593,6 +3635,8 @@ CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
|
||||
|
||||
CONFIG_BTRFS_FS=m
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
# Maybe see if we want this on for debug kernels?
|
||||
# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
|
||||
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
|
||||
@ -3764,6 +3808,7 @@ CONFIG_SECURITY_SELINUX_AVC_STATS=y
|
||||
# CONFIG_SECURITY_APPARMOR is not set
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_AUDITSYSCALL=y
|
||||
# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set
|
||||
|
||||
#
|
||||
# Cryptographic options
|
||||
@ -3902,6 +3947,7 @@ CONFIG_CGROUP_SCHED=y
|
||||
CONFIG_CGROUP_MEM_RES_CTLR=y
|
||||
CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y # XXX disabled by default, pass 'swapaccount'
|
||||
# CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set
|
||||
CONFIG_CGROUP_MEM_RES_CTLR_KMEM=y
|
||||
CONFIG_CGROUP_PERF=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
|
||||
@ -3986,6 +4032,7 @@ CONFIG_LEDS_CLASS=y
|
||||
# CONFIG_LEDS_BD2802 is not set
|
||||
# CONFIG_LEDS_S3C24XX is not set
|
||||
CONFIG_LEDS_DELL_NETBOOKS=m
|
||||
# CONFIG_LEDS_TCA6507 is not set
|
||||
CONFIG_LEDS_TRIGGERS=y
|
||||
CONFIG_LEDS_TRIGGER_TIMER=m
|
||||
CONFIG_LEDS_TRIGGER_IDE_DISK=y
|
||||
@ -4059,6 +4106,7 @@ CONFIG_APM_POWER=m
|
||||
|
||||
# CONFIG_BATTERY_DS2760 is not set
|
||||
# CONFIG_BATTERY_DS2782 is not set
|
||||
# CONFIG_BATTERY_SBS is not set
|
||||
# CONFIG_BATTERY_BQ20Z75 is not set
|
||||
# CONFIG_BATTERY_DS2780 is not set
|
||||
# CONFIG_BATTERY_BQ27x00 is not set
|
||||
@ -4067,6 +4115,7 @@ CONFIG_APM_POWER=m
|
||||
|
||||
# CONFIG_CHARGER_ISP1704 is not set
|
||||
# CONFIG_CHARGER_MAX8903 is not set
|
||||
# CONFIG_CHARGER_LP8727 is not set
|
||||
# CONFIG_CHARGER_GPIO is not set
|
||||
# CONFIG_CHARGER_PCF50633 is not set
|
||||
|
||||
@ -4169,6 +4218,8 @@ CONFIG_UWB_WHCI=m
|
||||
CONFIG_UWB_I1480U=m
|
||||
|
||||
CONFIG_STAGING=y
|
||||
# CONFIG_RTLLIB is not set
|
||||
# CONFIG_ANDROID is not set
|
||||
# CONFIG_STAGING_MEDIA is not set
|
||||
# CONFIG_ET131X is not set
|
||||
# CONFIG_SLICOSS is not set
|
||||
|
@ -352,3 +352,11 @@ CONFIG_RFKILL_GPIO=m
|
||||
|
||||
# Disable btrfs until it is shown to work with 64k pages (rhbz 747079)
|
||||
# CONFIG_BTRFS_FS is not set
|
||||
#
|
||||
# CONFIG_CPU_IDLE is not set
|
||||
# CONFIG_OF_SELFTEST is not set
|
||||
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
|
||||
# CONFIG_INPUT_GP2A is not set
|
||||
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
|
||||
CONFIG_STRICT_DEVMEM=y
|
||||
|
||||
|
@ -158,3 +158,7 @@ CONFIG_IO_EVENT_IRQ=y
|
||||
CONFIG_HW_RANDOM_AMD=m
|
||||
|
||||
CONFIG_BPF_JIT=y
|
||||
# CONFIG_PPC_ICSWX_PID is not set
|
||||
# CONFIG_PPC_ICSWX_USE_SIGILL is not set
|
||||
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
|
||||
|
||||
|
@ -195,3 +195,4 @@ CONFIG_CRYPTO_DEV_NIAGARA2=y
|
||||
# CONFIG_MTD_OF_PARTS is not set
|
||||
# CONFIG_MTD_PHYSMAP_OF is not set
|
||||
# CONFIG_MMC_SDHCI_OF is not set
|
||||
# CONFIG_OF_SELFTEST is not set
|
||||
|
@ -201,3 +201,7 @@ CONFIG_I2O_BUS=m
|
||||
# CONFIG_EDAC_SBRIDGE is not set
|
||||
|
||||
# CONFIG_X86_WANT_INTEL_MID is not set
|
||||
# CONFIG_OF_SELFTEST is not set
|
||||
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
|
||||
# CONFIG_INPUT_GP2A is not set
|
||||
# CONFIG_INPUT_GPIO_TILT_POLLED is not set
|
||||
|
@ -34,6 +34,7 @@ CONFIG_X86_PAT=y
|
||||
CONFIG_X86_PM_TIMER=y
|
||||
|
||||
CONFIG_EFI=y
|
||||
# CONFIG_EFI_STUB is not set
|
||||
CONFIG_EFI_VARS=y
|
||||
CONFIG_EFI_PCDP=y
|
||||
CONFIG_FB_EFI=y
|
||||
@ -113,6 +114,7 @@ CONFIG_PM_STD_PARTITION=""
|
||||
|
||||
CONFIG_PCI_MMCONFIG=y
|
||||
CONFIG_PCI_BIOS=y
|
||||
CONFIG_PCI_IOAPIC=y
|
||||
|
||||
CONFIG_HOTPLUG_PCI=y
|
||||
CONFIG_HOTPLUG_PCI_COMPAQ=m
|
||||
@ -216,6 +218,7 @@ CONFIG_XO15_EBOOK=m
|
||||
|
||||
# CONFIG_SMSC37B787_WDT is not set
|
||||
CONFIG_W83697HF_WDT=m
|
||||
CONFIG_VIA_WDT=m
|
||||
|
||||
CONFIG_CRASH_DUMP=y
|
||||
CONFIG_PROC_VMCORE=y
|
||||
@ -375,6 +378,7 @@ CONFIG_PCH_PHUB=m
|
||||
CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
|
||||
CONFIG_CRYPTO_AES_NI_INTEL=y
|
||||
CONFIG_CRYPTO_SERPENT_SSE2_586=m
|
||||
|
||||
CONFIG_HP_ACCEL=m
|
||||
|
||||
@ -389,3 +393,12 @@ CONFIG_RELOCATABLE=y
|
||||
|
||||
# CONFIG_HYPERV is not set
|
||||
|
||||
# Depends on HOTPLUG_PCI_PCIE
|
||||
CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m
|
||||
|
||||
# Figure out how this relates to DRM_PSB in staging because confused
|
||||
# CONFIG_DRM_GMA500 is not set
|
||||
|
||||
# Maybe enable in debug kernels?
|
||||
# CONFIG_DEBUG_NMI_SELFTEST is not set
|
||||
|
||||
|
@ -11,6 +11,7 @@ CONFIG_K8_NUMA=y
|
||||
CONFIG_AMD_NUMA=y
|
||||
CONFIG_X86_64_ACPI_NUMA=y
|
||||
# CONFIG_NUMA_EMU is not set
|
||||
# CONFIG_X86_NUMACHIP is not set
|
||||
|
||||
CONFIG_NR_CPUS=64
|
||||
CONFIG_PHYSICAL_START=0x1000000
|
||||
@ -20,6 +21,7 @@ CONFIG_IA32_EMULATION=y
|
||||
|
||||
CONFIG_AMD_IOMMU=y
|
||||
CONFIG_AMD_IOMMU_STATS=y
|
||||
CONFIG_AMD_IOMMU_V2=m
|
||||
# CONFIG_IOMMU_DEBUG is not set
|
||||
CONFIG_SWIOTLB=y
|
||||
# CONFIG_CALGARY_IOMMU is not set
|
||||
@ -35,6 +37,7 @@ CONFIG_ACPI_HOTPLUG_MEMORY=m
|
||||
CONFIG_HOTPLUG_PCI_SHPC=m
|
||||
|
||||
CONFIG_CRYPTO_AES_X86_64=y
|
||||
CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m
|
||||
CONFIG_CRYPTO_TWOFISH_X86_64=m
|
||||
CONFIG_CRYPTO_SALSA20_X86_64=m
|
||||
CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m
|
||||
|
@ -1,465 +0,0 @@
|
||||
From 0a6cc45426fe3baaf231efd7efe4300fd879efc8 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Baron <jbaron@redhat.com>
|
||||
Date: Mon, 24 Oct 2011 14:59:02 +1100
|
||||
Subject: [PATCH] epoll: limit paths
|
||||
|
||||
epoll: limit paths
|
||||
|
||||
The current epoll code can be tickled to run basically indefinitely in
|
||||
both loop detection path check (on ep_insert()), and in the wakeup paths.
|
||||
The programs that tickle this behavior set up deeply linked networks of
|
||||
epoll file descriptors that cause the epoll algorithms to traverse them
|
||||
indefinitely. A couple of these sample programs have been previously
|
||||
posted in this thread: https://lkml.org/lkml/2011/2/25/297.
|
||||
|
||||
To fix the loop detection path check algorithms, I simply keep track of
|
||||
the epoll nodes that have been already visited. Thus, the loop detection
|
||||
becomes proportional to the number of epoll file descriptor and links.
|
||||
This dramatically decreases the run-time of the loop check algorithm. In
|
||||
one diabolical case I tried it reduced the run-time from 15 mintues (all
|
||||
in kernel time) to .3 seconds.
|
||||
|
||||
Fixing the wakeup paths could be done at wakeup time in a similar manner
|
||||
by keeping track of nodes that have already been visited, but the
|
||||
complexity is harder, since there can be multiple wakeups on different
|
||||
cpus...Thus, I've opted to limit the number of possible wakeup paths when
|
||||
the paths are created.
|
||||
|
||||
This is accomplished, by noting that the end file descriptor points that
|
||||
are found during the loop detection pass (from the newly added link), are
|
||||
actually the sources for wakeup events. I keep a list of these file
|
||||
descriptors and limit the number and length of these paths that emanate
|
||||
from these 'source file descriptors'. In the current implemetation I
|
||||
allow 1000 paths of length 1, 500 of length 2, 100 of length 3, 50 of
|
||||
length 4 and 10 of length 5. Note that it is sufficient to check the
|
||||
'source file descriptors' reachable from the newly added link, since no
|
||||
other 'source file descriptors' will have newly added links. This allows
|
||||
us to check only the wakeup paths that may have gotten too long, and not
|
||||
re-check all possible wakeup paths on the system.
|
||||
|
||||
In terms of the path limit selection, I think its first worth noting that
|
||||
the most common case for epoll, is probably the model where you have 1
|
||||
epoll file descriptor that is monitoring n number of 'source file
|
||||
descriptors'. In this case, each 'source file descriptor' has a 1 path of
|
||||
length 1. Thus, I believe that the limits I'm proposing are quite
|
||||
reasonable and in fact may be too generous. Thus, I'm hoping that the
|
||||
proposed limits will not prevent any workloads that currently work to
|
||||
fail.
|
||||
|
||||
In terms of locking, I have extended the use of the 'epmutex' to all
|
||||
epoll_ctl add and remove operations. Currently its only used in a subset
|
||||
of the add paths. I need to hold the epmutex, so that we can correctly
|
||||
traverse a coherent graph, to check the number of paths. I believe that
|
||||
this additional locking is probably ok, since its in the setup/teardown
|
||||
paths, and doesn't affect the running paths, but it certainly is going to
|
||||
add some extra overhead. Also, worth noting is that the epmuex was
|
||||
recently added to the ep_ctl add operations in the initial path loop
|
||||
detection code using the argument that it was not on a critical path.
|
||||
|
||||
Another thing to note here, is the length of epoll chains that is allowed.
|
||||
Currently, eventpoll.c defines:
|
||||
|
||||
/* Maximum number of nesting allowed inside epoll sets */
|
||||
#define EP_MAX_NESTS 4
|
||||
|
||||
This basically means that I am limited to a graph depth of 5 (EP_MAX_NESTS
|
||||
+ 1). However, this limit is currently only enforced during the loop
|
||||
check detection code, and only when the epoll file descriptors are added
|
||||
in a certain order. Thus, this limit is currently easily bypassed. The
|
||||
newly added check for wakeup paths, stricly limits the wakeup paths to a
|
||||
length of 5, regardless of the order in which ep's are linked together.
|
||||
Thus, a side-effect of the new code is a more consistent enforcement of
|
||||
the graph depth.
|
||||
|
||||
Thus far, I've tested this, using the sample programs previously
|
||||
mentioned, which now either return quickly or return -EINVAL. I've also
|
||||
testing using the piptest.c epoll tester, which showed no difference in
|
||||
performance. I've also created a number of different epoll networks and
|
||||
tested that they behave as expectded.
|
||||
|
||||
I believe this solves the original diabolical test cases, while still
|
||||
preserving the sane epoll nesting.
|
||||
|
||||
Signed-off-by: Jason Baron <jbaron@redhat.com>
|
||||
Cc: Nelson Elhage <nelhage@ksplice.com>
|
||||
Cc: Davide Libenzi <davidel@xmailserver.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
fs/eventpoll.c | 226 ++++++++++++++++++++++++++++++++++++++++-----
|
||||
include/linux/eventpoll.h | 1 +
|
||||
include/linux/fs.h | 1 +
|
||||
3 files changed, 203 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
|
||||
index b84fad9..414ac74 100644
|
||||
--- a/fs/eventpoll.c
|
||||
+++ b/fs/eventpoll.c
|
||||
@@ -197,6 +197,12 @@ struct eventpoll {
|
||||
|
||||
/* The user that created the eventpoll descriptor */
|
||||
struct user_struct *user;
|
||||
+
|
||||
+ struct file *file;
|
||||
+
|
||||
+ /* used to optimize loop detection check */
|
||||
+ int visited;
|
||||
+ struct list_head visitedllink;
|
||||
};
|
||||
|
||||
/* Wait structure used by the poll hooks */
|
||||
@@ -255,6 +261,12 @@ static struct kmem_cache *epi_cache __read_mostly;
|
||||
/* Slab cache used to allocate "struct eppoll_entry" */
|
||||
static struct kmem_cache *pwq_cache __read_mostly;
|
||||
|
||||
+/* Visited nodes during ep_loop_check(), so we can unset them when we finish */
|
||||
+LIST_HEAD(visited_list);
|
||||
+
|
||||
+/* Files with newly added links, which need a limit on emanating paths */
|
||||
+LIST_HEAD(tfile_check_list);
|
||||
+
|
||||
#ifdef CONFIG_SYSCTL
|
||||
|
||||
#include <linux/sysctl.h>
|
||||
@@ -276,6 +288,12 @@ ctl_table epoll_table[] = {
|
||||
};
|
||||
#endif /* CONFIG_SYSCTL */
|
||||
|
||||
+static const struct file_operations eventpoll_fops;
|
||||
+
|
||||
+static inline int is_file_epoll(struct file *f)
|
||||
+{
|
||||
+ return f->f_op == &eventpoll_fops;
|
||||
+}
|
||||
|
||||
/* Setup the structure that is used as key for the RB tree */
|
||||
static inline void ep_set_ffd(struct epoll_filefd *ffd,
|
||||
@@ -711,12 +729,6 @@ static const struct file_operations eventpoll_fops = {
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
-/* Fast test to see if the file is an eventpoll file */
|
||||
-static inline int is_file_epoll(struct file *f)
|
||||
-{
|
||||
- return f->f_op == &eventpoll_fops;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* This is called from eventpoll_release() to unlink files from the eventpoll
|
||||
* interface. We need to have this facility to cleanup correctly files that are
|
||||
@@ -926,6 +938,96 @@ static void ep_rbtree_insert(struct eventpoll *ep, struct epitem *epi)
|
||||
rb_insert_color(&epi->rbn, &ep->rbr);
|
||||
}
|
||||
|
||||
+
|
||||
+
|
||||
+#define PATH_ARR_SIZE 5
|
||||
+/* These are the number paths of length 1 to 5, that we are allowing to emanate
|
||||
+ * from a single file of interest. For example, we allow 1000 paths of length
|
||||
+ * 1, to emanate from each file of interest. This essentially represents the
|
||||
+ * potential wakeup paths, which need to be limited in order to avoid massive
|
||||
+ * uncontrolled wakeup storms. The common use case should be a single ep which
|
||||
+ * is connected to n file sources. In this case each file source has 1 path
|
||||
+ * of length 1. Thus, the numbers below should be more than sufficient.
|
||||
+ */
|
||||
+int path_limits[PATH_ARR_SIZE] = { 1000, 500, 100, 50, 10 };
|
||||
+int path_count[PATH_ARR_SIZE];
|
||||
+
|
||||
+static int path_count_inc(int nests)
|
||||
+{
|
||||
+ if (++path_count[nests] > path_limits[nests])
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void path_count_init(void)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < PATH_ARR_SIZE; i++)
|
||||
+ path_count[i] = 0;
|
||||
+}
|
||||
+
|
||||
+static int reverse_path_check_proc(void *priv, void *cookie, int call_nests)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+ struct file *file = priv;
|
||||
+ struct file *child_file;
|
||||
+ struct epitem *epi;
|
||||
+
|
||||
+ list_for_each_entry(epi, &file->f_ep_links, fllink) {
|
||||
+ child_file = epi->ep->file;
|
||||
+ if (is_file_epoll(child_file)) {
|
||||
+ if (list_empty(&child_file->f_ep_links)) {
|
||||
+ if (path_count_inc(call_nests)) {
|
||||
+ error = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ } else {
|
||||
+ error = ep_call_nested(&poll_loop_ncalls,
|
||||
+ EP_MAX_NESTS,
|
||||
+ reverse_path_check_proc,
|
||||
+ child_file, child_file,
|
||||
+ current);
|
||||
+ }
|
||||
+ if (error != 0)
|
||||
+ break;
|
||||
+ } else {
|
||||
+ printk(KERN_ERR "reverse_path_check_proc: "
|
||||
+ "file is not an ep!\n");
|
||||
+ }
|
||||
+ }
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * reverse_path_check - The tfile_check_list is list of file *, which have
|
||||
+ * links that are proposed to be newly added. We need to
|
||||
+ * make sure that those added links don't add too many
|
||||
+ * paths such that we will spend all our time waking up
|
||||
+ * eventpoll objects.
|
||||
+ *
|
||||
+ * Returns: Returns zero if the proposed links don't create too many paths,
|
||||
+ * -1 otherwise.
|
||||
+ */
|
||||
+static int reverse_path_check(void)
|
||||
+{
|
||||
+ int length = 0;
|
||||
+ int error = 0;
|
||||
+ struct file *current_file;
|
||||
+
|
||||
+ /* let's call this for all tfiles */
|
||||
+ list_for_each_entry(current_file, &tfile_check_list, f_tfile_llink) {
|
||||
+ length++;
|
||||
+ path_count_init();
|
||||
+ error = ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
|
||||
+ reverse_path_check_proc, current_file,
|
||||
+ current_file, current);
|
||||
+ if (error)
|
||||
+ break;
|
||||
+ }
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Must be called with "mtx" held.
|
||||
*/
|
||||
@@ -987,6 +1089,11 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
|
||||
*/
|
||||
ep_rbtree_insert(ep, epi);
|
||||
|
||||
+ /* now check if we've created too many backpaths */
|
||||
+ error = -EINVAL;
|
||||
+ if (reverse_path_check())
|
||||
+ goto error_remove_epi;
|
||||
+
|
||||
/* We have to drop the new item inside our item list to keep track of it */
|
||||
spin_lock_irqsave(&ep->lock, flags);
|
||||
|
||||
@@ -1011,6 +1118,14 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event,
|
||||
|
||||
return 0;
|
||||
|
||||
+error_remove_epi:
|
||||
+ spin_lock(&tfile->f_lock);
|
||||
+ if (ep_is_linked(&epi->fllink))
|
||||
+ list_del_init(&epi->fllink);
|
||||
+ spin_unlock(&tfile->f_lock);
|
||||
+
|
||||
+ rb_erase(&epi->rbn, &ep->rbr);
|
||||
+
|
||||
error_unregister:
|
||||
ep_unregister_pollwait(ep, epi);
|
||||
|
||||
@@ -1275,18 +1390,35 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
|
||||
int error = 0;
|
||||
struct file *file = priv;
|
||||
struct eventpoll *ep = file->private_data;
|
||||
+ struct eventpoll *ep_tovisit;
|
||||
struct rb_node *rbp;
|
||||
struct epitem *epi;
|
||||
|
||||
mutex_lock_nested(&ep->mtx, call_nests + 1);
|
||||
+ ep->visited = 1;
|
||||
+ list_add(&ep->visitedllink, &visited_list);
|
||||
for (rbp = rb_first(&ep->rbr); rbp; rbp = rb_next(rbp)) {
|
||||
epi = rb_entry(rbp, struct epitem, rbn);
|
||||
if (unlikely(is_file_epoll(epi->ffd.file))) {
|
||||
+ ep_tovisit = epi->ffd.file->private_data;
|
||||
+ if (ep_tovisit->visited)
|
||||
+ continue;
|
||||
error = ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
|
||||
- ep_loop_check_proc, epi->ffd.file,
|
||||
- epi->ffd.file->private_data, current);
|
||||
+ ep_loop_check_proc, epi->ffd.file,
|
||||
+ ep_tovisit, current);
|
||||
if (error != 0)
|
||||
break;
|
||||
+ } else {
|
||||
+ /* if we've reached a file that is not associated with
|
||||
+ * an ep, then then we need to check if the newly added
|
||||
+ * links are going to add too many wakeup paths. We do
|
||||
+ * this by adding it to the tfile_check_list, if it's
|
||||
+ * not already there, and calling reverse_path_check()
|
||||
+ * during ep_insert()
|
||||
+ */
|
||||
+ if (list_empty(&epi->ffd.file->f_tfile_llink))
|
||||
+ list_add(&epi->ffd.file->f_tfile_llink,
|
||||
+ &tfile_check_list);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ep->mtx);
|
||||
@@ -1307,8 +1439,30 @@ static int ep_loop_check_proc(void *priv, void *cookie, int call_nests)
|
||||
*/
|
||||
static int ep_loop_check(struct eventpoll *ep, struct file *file)
|
||||
{
|
||||
- return ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
|
||||
+ int ret;
|
||||
+ struct eventpoll *ep_cur, *ep_next;
|
||||
+
|
||||
+ ret = ep_call_nested(&poll_loop_ncalls, EP_MAX_NESTS,
|
||||
ep_loop_check_proc, file, ep, current);
|
||||
+ /* clear visited list */
|
||||
+ list_for_each_entry_safe(ep_cur, ep_next, &visited_list, visitedllink) {
|
||||
+ ep_cur->visited = 0;
|
||||
+ list_del(&ep_cur->visitedllink);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void clear_tfile_check_list(void)
|
||||
+{
|
||||
+ struct file *file;
|
||||
+
|
||||
+ /* first clear the tfile_check_list */
|
||||
+ while (!list_empty(&tfile_check_list)) {
|
||||
+ file = list_first_entry(&tfile_check_list, struct file,
|
||||
+ f_tfile_llink);
|
||||
+ list_del_init(&file->f_tfile_llink);
|
||||
+ }
|
||||
+ INIT_LIST_HEAD(&tfile_check_list);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1316,8 +1470,9 @@ static int ep_loop_check(struct eventpoll *ep, struct file *file)
|
||||
*/
|
||||
SYSCALL_DEFINE1(epoll_create1, int, flags)
|
||||
{
|
||||
- int error;
|
||||
+ int error, fd;
|
||||
struct eventpoll *ep = NULL;
|
||||
+ struct file *file;
|
||||
|
||||
/* Check the EPOLL_* constant for consistency. */
|
||||
BUILD_BUG_ON(EPOLL_CLOEXEC != O_CLOEXEC);
|
||||
@@ -1334,11 +1489,25 @@ SYSCALL_DEFINE1(epoll_create1, int, flags)
|
||||
* Creates all the items needed to setup an eventpoll file. That is,
|
||||
* a file structure and a free file descriptor.
|
||||
*/
|
||||
- error = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep,
|
||||
+ fd = get_unused_fd_flags(O_RDWR | (flags & O_CLOEXEC));
|
||||
+ if (fd < 0) {
|
||||
+ error = fd;
|
||||
+ goto out_free_ep;
|
||||
+ }
|
||||
+ file = anon_inode_getfile("[eventpoll]", &eventpoll_fops, ep,
|
||||
O_RDWR | (flags & O_CLOEXEC));
|
||||
- if (error < 0)
|
||||
- ep_free(ep);
|
||||
-
|
||||
+ if (IS_ERR(file)) {
|
||||
+ error = PTR_ERR(file);
|
||||
+ goto out_free_fd;
|
||||
+ }
|
||||
+ fd_install(fd, file);
|
||||
+ ep->file = file;
|
||||
+ return fd;
|
||||
+
|
||||
+out_free_fd:
|
||||
+ put_unused_fd(fd);
|
||||
+out_free_ep:
|
||||
+ ep_free(ep);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1404,21 +1573,27 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
/*
|
||||
* When we insert an epoll file descriptor, inside another epoll file
|
||||
* descriptor, there is the change of creating closed loops, which are
|
||||
- * better be handled here, than in more critical paths.
|
||||
+ * better be handled here, than in more critical paths. While we are
|
||||
+ * checking for loops we also determine the list of files reachable
|
||||
+ * and hang them on the tfile_check_list, so we can check that we
|
||||
+ * haven't created too many possible wakeup paths.
|
||||
*
|
||||
- * We hold epmutex across the loop check and the insert in this case, in
|
||||
- * order to prevent two separate inserts from racing and each doing the
|
||||
- * insert "at the same time" such that ep_loop_check passes on both
|
||||
- * before either one does the insert, thereby creating a cycle.
|
||||
+ * We need to hold the epmutex across both ep_insert and ep_remove
|
||||
+ * b/c we want to make sure we are looking at a coherent view of
|
||||
+ * epoll network.
|
||||
*/
|
||||
- if (unlikely(is_file_epoll(tfile) && op == EPOLL_CTL_ADD)) {
|
||||
+ if (op == EPOLL_CTL_ADD || op == EPOLL_CTL_DEL) {
|
||||
mutex_lock(&epmutex);
|
||||
did_lock_epmutex = 1;
|
||||
- error = -ELOOP;
|
||||
- if (ep_loop_check(ep, tfile) != 0)
|
||||
- goto error_tgt_fput;
|
||||
}
|
||||
-
|
||||
+ if (op == EPOLL_CTL_ADD) {
|
||||
+ if (is_file_epoll(tfile)) {
|
||||
+ error = -ELOOP;
|
||||
+ if (ep_loop_check(ep, tfile) != 0)
|
||||
+ goto error_tgt_fput;
|
||||
+ } else
|
||||
+ list_add(&tfile->f_tfile_llink, &tfile_check_list);
|
||||
+ }
|
||||
|
||||
mutex_lock_nested(&ep->mtx, 0);
|
||||
|
||||
@@ -1437,6 +1612,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
error = ep_insert(ep, &epds, tfile, fd);
|
||||
} else
|
||||
error = -EEXIST;
|
||||
+ clear_tfile_check_list();
|
||||
break;
|
||||
case EPOLL_CTL_DEL:
|
||||
if (epi)
|
||||
@@ -1455,7 +1631,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
|
||||
mutex_unlock(&ep->mtx);
|
||||
|
||||
error_tgt_fput:
|
||||
- if (unlikely(did_lock_epmutex))
|
||||
+ if (did_lock_epmutex)
|
||||
mutex_unlock(&epmutex);
|
||||
|
||||
fput(tfile);
|
||||
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h
|
||||
index f362733..657ab55 100644
|
||||
--- a/include/linux/eventpoll.h
|
||||
+++ b/include/linux/eventpoll.h
|
||||
@@ -61,6 +61,7 @@ struct file;
|
||||
static inline void eventpoll_init_file(struct file *file)
|
||||
{
|
||||
INIT_LIST_HEAD(&file->f_ep_links);
|
||||
+ INIT_LIST_HEAD(&file->f_tfile_llink);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/include/linux/fs.h b/include/linux/fs.h
|
||||
index ba98668..d393a68 100644
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -985,6 +985,7 @@ struct file {
|
||||
#ifdef CONFIG_EPOLL
|
||||
/* Used by fs/eventpoll.c to link all the hooks to this file */
|
||||
struct list_head f_ep_links;
|
||||
+ struct list_head f_tfile_llink;
|
||||
#endif /* #ifdef CONFIG_EPOLL */
|
||||
struct address_space *f_mapping;
|
||||
#ifdef CONFIG_DEBUG_WRITECOUNT
|
||||
--
|
||||
1.7.6.4
|
||||
|
@ -1,19 +0,0 @@
|
||||
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
|
||||
index 00beb4f..8fb6844 100644
|
||||
--- a/fs/ext4/ialloc.c
|
||||
+++ b/fs/ext4/ialloc.c
|
||||
@@ -885,8 +885,12 @@ got:
|
||||
if (IS_DIRSYNC(inode))
|
||||
ext4_handle_sync(handle);
|
||||
if (insert_inode_locked(inode) < 0) {
|
||||
- err = -EINVAL;
|
||||
- goto fail_drop;
|
||||
+ /*
|
||||
+ * Likely a bitmap corruption causing inode to be allocated
|
||||
+ * twice.
|
||||
+ */
|
||||
+ err = -EIO;
|
||||
+ goto fail;
|
||||
}
|
||||
spin_lock(&sbi->s_next_gen_lock);
|
||||
inode->i_generation = sbi->s_next_generation++;
|
98
kernel.spec
98
kernel.spec
@ -6,7 +6,7 @@ Summary: The Linux kernel
|
||||
# For a stable, released kernel, released_kernel should be 1. For rawhide
|
||||
# and/or a kernel built from an rc or git snapshot, released_kernel should
|
||||
# be 0.
|
||||
%global released_kernel 1
|
||||
%global released_kernel 0
|
||||
|
||||
# Save original buildid for later if it's defined
|
||||
%if 0%{?buildid:1}
|
||||
@ -54,7 +54,7 @@ Summary: The Linux kernel
|
||||
# For non-released -rc kernels, this will be appended after the rcX and
|
||||
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
|
||||
#
|
||||
%global baserelease 8
|
||||
%global baserelease 1
|
||||
%global fedora_build %{baserelease}
|
||||
|
||||
# base_sublevel is the kernel version we're starting with and patching
|
||||
@ -66,7 +66,7 @@ Summary: The Linux kernel
|
||||
%if 0%{?released_kernel}
|
||||
|
||||
# Do we have a -stable update to apply?
|
||||
%define stable_update 1
|
||||
%define stable_update 0
|
||||
# Is it a -stable RC?
|
||||
%define stable_rc 0
|
||||
# Set rpm version accordingly
|
||||
@ -85,9 +85,9 @@ Summary: The Linux kernel
|
||||
# The next upstream release sublevel (base_sublevel+1)
|
||||
%define upstream_sublevel %(echo $((%{base_sublevel} + 1)))
|
||||
# The rc snapshot level
|
||||
%define rcrev 7
|
||||
%define rcrev 1
|
||||
# The git snapshot level
|
||||
%define gitrev 5
|
||||
%define gitrev 0
|
||||
# Set rpm version accordingly
|
||||
%define rpmversion 3.%{upstream_sublevel}.0
|
||||
%endif
|
||||
@ -218,7 +218,7 @@ Summary: The Linux kernel
|
||||
#
|
||||
# (Uncomment the '#' and both spaces below to disable with_backports.)
|
||||
#
|
||||
# % define with_backports 0
|
||||
%define with_backports 0
|
||||
#######################################################################
|
||||
|
||||
%define make_target bzImage
|
||||
@ -719,8 +719,7 @@ Patch1101: linux-3.1-keys-remove-special-keyring.patch
|
||||
# patches headed upstream
|
||||
Patch12016: disable-i8042-check-on-apple-mac.patch
|
||||
|
||||
Patch12026: block-stray-block-put-after-teardown.patch
|
||||
Patch12030: epoll-limit-paths.patch
|
||||
#atch12026: block-stray-block-put-after-teardown.patch
|
||||
|
||||
Patch12303: dmar-disable-when-ricoh-multifunction.patch
|
||||
|
||||
@ -733,53 +732,20 @@ Patch20000: utrace.patch
|
||||
Patch21000: arm-omap-dt-compat.patch
|
||||
Patch21001: arm-smsc-support-reading-mac-address-from-device-tree.patch
|
||||
|
||||
#rhbz 753236
|
||||
Patch21029: nfsv4-include-bitmap-in-nfsv4_get_acl_data.patch
|
||||
|
||||
#rhbz 590880
|
||||
Patch21030: alps.patch
|
||||
|
||||
#rhbz 717735
|
||||
Patch21045: nfs-client-freezer.patch
|
||||
|
||||
#rhbz 770233
|
||||
Patch21065: Bluetooth-Add-support-for-BCM20702A0-0a5c-21e3.patch
|
||||
|
||||
Patch21070: ext4-Support-check-none-nocheck-mount-options.patch
|
||||
Patch21071: ext4-Fix-error-handling-on-inode-bitmap-corruption.patch
|
||||
|
||||
#rhbz 769766
|
||||
Patch21072: mac80211-fix-rx-key-NULL-ptr-deref-in-promiscuous-mode.patch
|
||||
|
||||
#rhbz 773392
|
||||
Patch21073: KVM-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch
|
||||
Patch21074: KVM-x86-fix-missing-checks-in-syscall-emulation.patch
|
||||
|
||||
#rhbz 728740
|
||||
Patch21076: rtl8192cu-Fix-WARNING-on-suspend-resume.patch
|
||||
|
||||
Patch21080: sysfs-msi-irq-per-device.patch
|
||||
|
||||
#rhbz 782686
|
||||
Patch21082: procfs-parse-mount-options.patch
|
||||
Patch21083: procfs-add-hidepid-and-gid-mount-options.patch
|
||||
Patch21084: proc-fix-null-pointer-deref-in-proc_pid_permission.patch
|
||||
|
||||
#rhbz 782681
|
||||
Patch21085: proc-clean-up-and-fix-proc-pid-mem-handling.patch
|
||||
|
||||
#rhbz 782696
|
||||
Patch21086: Unused-iocbs-in-a-batch-should-not-be-accounted-as-a.patch
|
||||
|
||||
Patch21090: bcma-brcmsmac-compat.patch
|
||||
|
||||
Patch21091: pci-Rework-ASPM-disable-code.patch
|
||||
Patch21091: kmemleak.patch
|
||||
|
||||
# compat-wireless patches
|
||||
Patch50000: compat-wireless-config-fixups.patch
|
||||
Patch50001: compat-wireless-pr_fmt-warning-avoidance.patch
|
||||
Patch50002: compat-wireless-integrated-build.patch
|
||||
Patch50003: compat-wireless-rtl8192cu-Fix-WARNING-on-suspend-resume.patch
|
||||
|
||||
Patch50100: brcmfmac-gcc47.patch
|
||||
|
||||
@ -1341,7 +1307,7 @@ ApplyPatch linux-2.6-i386-nx-emulation.patch
|
||||
#
|
||||
# ARM
|
||||
#
|
||||
ApplyPatch arm-omap-dt-compat.patch
|
||||
#pplyPatch arm-omap-dt-compat.patch
|
||||
ApplyPatch arm-smsc-support-reading-mac-address-from-device-tree.patch
|
||||
|
||||
#
|
||||
@ -1448,8 +1414,7 @@ ApplyOptionalPatch linux-2.6-v4l-dvb-experimental.patch
|
||||
# Patches headed upstream
|
||||
ApplyPatch disable-i8042-check-on-apple-mac.patch
|
||||
|
||||
ApplyPatch epoll-limit-paths.patch
|
||||
ApplyPatch block-stray-block-put-after-teardown.patch
|
||||
#pplyPatch block-stray-block-put-after-teardown.patch
|
||||
|
||||
# rhbz#605888
|
||||
ApplyPatch dmar-disable-when-ricoh-multifunction.patch
|
||||
@ -1458,54 +1423,20 @@ ApplyPatch revert-efi-rtclock.patch
|
||||
ApplyPatch efi-dont-map-boot-services-on-32bit.patch
|
||||
|
||||
# utrace.
|
||||
ApplyPatch utrace.patch
|
||||
|
||||
# Add msi irq ennumeration in sysfs for devices
|
||||
ApplyPatch sysfs-msi-irq-per-device.patch
|
||||
# pplyPatch utrace.patch
|
||||
|
||||
%if !%{with_backports}
|
||||
# Remove overlap between bcma/b43 and brcmsmac and reenable bcm4331
|
||||
ApplyPatch bcma-brcmsmac-compat.patch
|
||||
%endif
|
||||
|
||||
ApplyPatch pci-Rework-ASPM-disable-code.patch
|
||||
|
||||
#rhbz 753236
|
||||
ApplyPatch nfsv4-include-bitmap-in-nfsv4_get_acl_data.patch
|
||||
|
||||
#rhbz 590880
|
||||
ApplyPatch alps.patch
|
||||
|
||||
#rhbz 717735
|
||||
ApplyPatch nfs-client-freezer.patch
|
||||
|
||||
#rhbz 770233
|
||||
ApplyPatch Bluetooth-Add-support-for-BCM20702A0-0a5c-21e3.patch
|
||||
|
||||
ApplyPatch ext4-Support-check-none-nocheck-mount-options.patch
|
||||
|
||||
ApplyPatch ext4-Fix-error-handling-on-inode-bitmap-corruption.patch
|
||||
|
||||
ApplyPatch mac80211-fix-rx-key-NULL-ptr-deref-in-promiscuous-mode.patch
|
||||
|
||||
#rhbz 773392
|
||||
ApplyPatch KVM-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch
|
||||
ApplyPatch KVM-x86-fix-missing-checks-in-syscall-emulation.patch
|
||||
|
||||
#rhbz 728740
|
||||
ApplyPatch rtl8192cu-Fix-WARNING-on-suspend-resume.patch
|
||||
|
||||
#rhbz 782686
|
||||
ApplyPatch procfs-parse-mount-options.patch
|
||||
ApplyPatch procfs-add-hidepid-and-gid-mount-options.patch
|
||||
ApplyPatch proc-fix-null-pointer-deref-in-proc_pid_permission.patch
|
||||
|
||||
#rhbz 782681
|
||||
ApplyPatch proc-clean-up-and-fix-proc-pid-mem-handling.patch
|
||||
|
||||
#rhbz 782696
|
||||
ApplyPatch Unused-iocbs-in-a-batch-should-not-be-accounted-as-a.patch
|
||||
|
||||
ApplyPatch kmemleak.patch
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
%endif
|
||||
@ -1571,8 +1502,6 @@ cd compat-wireless-%{cwversion}
|
||||
ApplyPatch compat-wireless-config-fixups.patch
|
||||
ApplyPatch compat-wireless-pr_fmt-warning-avoidance.patch
|
||||
ApplyPatch compat-wireless-integrated-build.patch
|
||||
ApplyPatch compat-wireless-rtl8192cu-Fix-WARNING-on-suspend-resume.patch
|
||||
ApplyPatch mac80211-fix-rx-key-NULL-ptr-deref-in-promiscuous-mode.patch
|
||||
|
||||
ApplyPatch brcmfmac-gcc47.patch
|
||||
|
||||
@ -2345,6 +2274,9 @@ fi
|
||||
# ||----w |
|
||||
# || ||
|
||||
%changelog
|
||||
* Fri Jan 20 2012 Josh Boyer <jwboyer@redhat.com>
|
||||
- Rebase to Linux 3.3-rc1
|
||||
|
||||
* Thu Jan 19 2012 John W. Linville <linville@redhat.com>
|
||||
- Pass the same make options to compat-wireless as to the base kernel
|
||||
|
||||
|
100
kmemleak.patch
Normal file
100
kmemleak.patch
Normal file
@ -0,0 +1,100 @@
|
||||
|
||||
Delivered-To: jwboyer@gmail.com
|
||||
Received: by 10.216.166.66 with SMTP id f44cs7120wel;
|
||||
Fri, 20 Jan 2012 03:02:14 -0800 (PST)
|
||||
Received: by 10.68.72.8 with SMTP id z8mr60494730pbu.111.1327057318390;
|
||||
Fri, 20 Jan 2012 03:01:58 -0800 (PST)
|
||||
Return-Path: <linux-kernel-owner@vger.kernel.org>
|
||||
Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67])
|
||||
by mx.google.com with ESMTP id q8si4181579pbn.101.2012.01.20.03.01.56;
|
||||
Fri, 20 Jan 2012 03:01:58 -0800 (PST)
|
||||
Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67;
|
||||
Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mail=linux-kernel-owner@vger.kernel.org
|
||||
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
||||
id S1751460Ab2ATLBU (ORCPT <rfc822;ramashish.lists@gmail.com>
|
||||
+ 99 others); Fri, 20 Jan 2012 06:01:20 -0500
|
||||
Received: from cam-admin0.cambridge.arm.com ([217.140.96.50]:34737 "EHLO
|
||||
cam-admin0.cambridge.arm.com" rhost-flags-OK-OK-OK-OK)
|
||||
by vger.kernel.org with ESMTP id S1750877Ab2ATLBT (ORCPT
|
||||
<rfc822;linux-kernel@vger.kernel.org>);
|
||||
Fri, 20 Jan 2012 06:01:19 -0500
|
||||
Received: from arm.com (e102109-lin.cambridge.arm.com [10.1.69.68])
|
||||
by cam-admin0.cambridge.arm.com (8.12.6/8.12.6) with ESMTP id q0KB1CWq000059;
|
||||
Fri, 20 Jan 2012 11:01:12 GMT
|
||||
Date: Fri, 20 Jan 2012 11:01:11 +0000
|
||||
From: Catalin Marinas <catalin.marinas@arm.com>
|
||||
To: Dirk Gouders <gouders@et.bocholt.fh-gelsenkirchen.de>
|
||||
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
|
||||
Subject: Re: [Problem] kernel hangs at boot (bisected 892d208bcf)
|
||||
Message-ID: <20120120110111.GB30612@arm.com>
|
||||
References: <gi39bcyff8.fsf@mx10.gouders.net>
|
||||
<20120119110121.GC9268@arm.com>
|
||||
<gi1uqvsx8n.fsf@karga.hank.lab>
|
||||
<20120119140058.GA19036@arm.com>
|
||||
<gik44nrc52.fsf@karga.hank.lab>
|
||||
<20120119153732.GB20558@arm.com>
|
||||
<gi1uqvwpt2.fsf@mx10.gouders.net>
|
||||
<gimx9jv50u.fsf@mx10.gouders.net>
|
||||
<giipk7v2hv.fsf@mx10.gouders.net>
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Disposition: inline
|
||||
In-Reply-To: <giipk7v2hv.fsf@mx10.gouders.net>
|
||||
Thread-Topic: [Problem] kernel hangs at boot (bisected 892d208bcf)
|
||||
Accept-Language: en-GB, en-US
|
||||
Content-Language: en-US
|
||||
User-Agent: Mutt/1.5.20 (2009-06-14)
|
||||
Sender: linux-kernel-owner@vger.kernel.org
|
||||
Precedence: bulk
|
||||
List-ID: <linux-kernel.vger.kernel.org>
|
||||
X-Mailing-List: linux-kernel@vger.kernel.org
|
||||
|
||||
On Thu, Jan 19, 2012 at 08:52:44PM +0000, Dirk Gouders wrote:
|
||||
> Dirk Gouders <gouders@et.bocholt.fh-gelsenkirchen.de> writes:
|
||||
> I want to note that in my config CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF is
|
||||
> set which causes kmemleak_disable() to be called in kmemleak_init().
|
||||
|
||||
Thanks for the investigation. Could you please try the patch below?
|
||||
Thanks.
|
||||
|
||||
|
||||
From 09e7bd41ff3fd07e4c5eea7bbb0a045921eb5944 Mon Sep 17 00:00:00 2001
|
||||
From: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Date: Fri, 20 Jan 2012 10:42:40 +0000
|
||||
Subject: [PATCH] kmemleak: Disable early logging when kmemleak is off by
|
||||
default
|
||||
|
||||
Commit b6693005 (kmemleak: When the early log buffer is exceeded, report
|
||||
the actual number) deferred the disabling of the early logging to
|
||||
kmemleak_init(). However, when CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y, the
|
||||
early logging was no longer disabled causing __init kmemleak functions
|
||||
to be called even after the kernel freed the init memory. This patch
|
||||
disables the early logging during kmemleak_init() if kmemleak is left
|
||||
disabled.
|
||||
|
||||
Reported-by: Dirk Gouders <gouders@et.bocholt.fh-gelsenkirchen.de>
|
||||
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
|
||||
---
|
||||
mm/kmemleak.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
|
||||
index f9f7310..45eb621 100644
|
||||
--- a/mm/kmemleak.c
|
||||
+++ b/mm/kmemleak.c
|
||||
@@ -1757,6 +1757,7 @@ void __init kmemleak_init(void)
|
||||
|
||||
#ifdef CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF
|
||||
if (!kmemleak_skip_disable) {
|
||||
+ atomic_set(&kmemleak_early_log, 0);
|
||||
kmemleak_disable();
|
||||
return;
|
||||
}
|
||||
|
||||
--
|
||||
Catalin
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
Please read the FAQ at http://www.tux.org/lkml/
|
@ -1,13 +1,13 @@
|
||||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
|
||||
index d8d7596..a1b7117 100644
|
||||
index eaef02a..2029819 100644
|
||||
--- a/drivers/acpi/video.c
|
||||
+++ b/drivers/acpi/video.c
|
||||
@@ -71,7 +71,7 @@ MODULE_AUTHOR("Bruno Ducrot");
|
||||
@@ -69,7 +69,7 @@ MODULE_AUTHOR("Bruno Ducrot");
|
||||
MODULE_DESCRIPTION("ACPI Video Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
-static int brightness_switch_enabled = 1;
|
||||
+static int brightness_switch_enabled = 0;
|
||||
-static bool brightness_switch_enabled = 1;
|
||||
+static bool brightness_switch_enabled = 0;
|
||||
module_param(brightness_switch_enabled, bool, 0644);
|
||||
|
||||
static int acpi_video_bus_add(struct acpi_device *device);
|
||||
/*
|
||||
|
@ -1,47 +0,0 @@
|
||||
Since:
|
||||
|
||||
commit 816c04fe7ef01dd9649f5ccfe796474db8708be5
|
||||
Author: Christian Lamparter <chunkeey@googlemail.com>
|
||||
Date: Sat Apr 30 15:24:30 2011 +0200
|
||||
|
||||
mac80211: consolidate MIC failure report handling
|
||||
|
||||
is possible to that we dereference rx->key == NULL when driver set
|
||||
RX_FLAG_MMIC_STRIPPED and not RX_FLAG_IV_STRIPPED and we are in
|
||||
promiscuous mode. This happen with rt73usb and rt61pci at least.
|
||||
|
||||
Before the commit we always check rx->key against NULL, so I assume
|
||||
fix should be done in mac80211 (also mic_fail path has similar check).
|
||||
|
||||
References:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=769766
|
||||
http://rt2x00.serialmonkey.com/pipermail/users_rt2x00.serialmonkey.com/2012-January/004395.html
|
||||
|
||||
Cc: stable@vger.kernel.org # 3.0+
|
||||
Reported-by: Stuart D Gathman <stuart@gathman.org>
|
||||
Reported-by: Kai Wohlfahrt <kai.scorpio@gmail.com>
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
---
|
||||
net/mac80211/wpa.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
|
||||
index 93aab07..422b798 100644
|
||||
--- a/net/mac80211/wpa.c
|
||||
+++ b/net/mac80211/wpa.c
|
||||
@@ -106,7 +106,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
|
||||
if (status->flag & RX_FLAG_MMIC_ERROR)
|
||||
goto mic_fail;
|
||||
|
||||
- if (!(status->flag & RX_FLAG_IV_STRIPPED))
|
||||
+ if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key)
|
||||
goto update_iv;
|
||||
|
||||
return RX_CONTINUE;
|
||||
--
|
||||
1.7.1
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
@ -1,197 +0,0 @@
|
||||
@@ -, +, @@
|
||||
fs/nfs/inode.c | 3 ++-
|
||||
fs/nfs/nfs3proc.c | 3 ++-
|
||||
fs/nfs/nfs4proc.c | 5 +++--
|
||||
fs/nfs/proc.c | 3 ++-
|
||||
include/linux/freezer.h | 28 ++++++++++++++++++++++++++++
|
||||
net/sunrpc/sched.c | 3 ++-
|
||||
6 files changed, 39 insertions(+), 6 deletions(-)
|
||||
--- a/fs/nfs/inode.c
|
||||
+++ a/fs/nfs/inode.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <linux/nfs_xdr.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/compat.h>
|
||||
+#include <linux/freezer.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
@@ -77,7 +78,7 @@ int nfs_wait_bit_killable(void *word)
|
||||
{
|
||||
if (fatal_signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
- schedule();
|
||||
+ freezable_schedule();
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/fs/nfs/nfs3proc.c
|
||||
+++ a/fs/nfs/nfs3proc.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/nfs_page.h>
|
||||
#include <linux/lockd/bind.h>
|
||||
#include <linux/nfs_mount.h>
|
||||
+#include <linux/freezer.h>
|
||||
|
||||
#include "iostat.h"
|
||||
#include "internal.h"
|
||||
@@ -32,7 +33,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
|
||||
res = rpc_call_sync(clnt, msg, flags);
|
||||
if (res != -EJUKEBOX && res != -EKEYEXPIRED)
|
||||
break;
|
||||
- schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
|
||||
+ freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
|
||||
res = -ERESTARTSYS;
|
||||
} while (!fatal_signal_pending(current));
|
||||
return res;
|
||||
--- a/fs/nfs/nfs4proc.c
|
||||
+++ a/fs/nfs/nfs4proc.c
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <linux/sunrpc/bc_xprt.h>
|
||||
#include <linux/xattr.h>
|
||||
#include <linux/utsname.h>
|
||||
+#include <linux/freezer.h>
|
||||
|
||||
#include "nfs4_fs.h"
|
||||
#include "delegation.h"
|
||||
@@ -241,7 +242,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
|
||||
*timeout = NFS4_POLL_RETRY_MIN;
|
||||
if (*timeout > NFS4_POLL_RETRY_MAX)
|
||||
*timeout = NFS4_POLL_RETRY_MAX;
|
||||
- schedule_timeout_killable(*timeout);
|
||||
+ freezable_schedule_timeout_killable(*timeout);
|
||||
if (fatal_signal_pending(current))
|
||||
res = -ERESTARTSYS;
|
||||
*timeout <<= 1;
|
||||
@@ -3950,7 +3951,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
|
||||
static unsigned long
|
||||
nfs4_set_lock_task_retry(unsigned long timeout)
|
||||
{
|
||||
- schedule_timeout_killable(timeout);
|
||||
+ freezable_schedule_timeout_killable(timeout);
|
||||
timeout <<= 1;
|
||||
if (timeout > NFS4_LOCK_MAXTIMEOUT)
|
||||
return NFS4_LOCK_MAXTIMEOUT;
|
||||
--- a/fs/nfs/proc.c
|
||||
+++ a/fs/nfs/proc.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <linux/nfs_fs.h>
|
||||
#include <linux/nfs_page.h>
|
||||
#include <linux/lockd/bind.h>
|
||||
+#include <linux/freezer.h>
|
||||
#include "internal.h"
|
||||
|
||||
#define NFSDBG_FACILITY NFSDBG_PROC
|
||||
@@ -59,7 +60,7 @@ nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
|
||||
res = rpc_call_sync(clnt, msg, flags);
|
||||
if (res != -EKEYEXPIRED)
|
||||
break;
|
||||
- schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
|
||||
+ freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
|
||||
res = -ERESTARTSYS;
|
||||
} while (!fatal_signal_pending(current));
|
||||
return res;
|
||||
--- a/include/linux/freezer.h
|
||||
+++ a/include/linux/freezer.h
|
||||
@@ -135,6 +135,29 @@ static inline void set_freezable_with_signal(void)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * These macros are intended to be used whenever you want allow a task that's
|
||||
+ * sleeping in TASK_UNINTERRUPTIBLE or TASK_KILLABLE state to be frozen. Note
|
||||
+ * that neither return any clear indication of whether a freeze event happened
|
||||
+ * while in this function.
|
||||
+ */
|
||||
+
|
||||
+/* Like schedule(), but should not block the freezer. */
|
||||
+#define freezable_schedule() \
|
||||
+({ \
|
||||
+ freezer_do_not_count(); \
|
||||
+ schedule(); \
|
||||
+ freezer_count(); \
|
||||
+})
|
||||
+
|
||||
+/* Like schedule_timeout_killable(), but should not block the freezer. */
|
||||
+#define freezable_schedule_timeout_killable(timeout) \
|
||||
+({ \
|
||||
+ freezer_do_not_count(); \
|
||||
+ schedule_timeout_killable(timeout); \
|
||||
+ freezer_count(); \
|
||||
+})
|
||||
+
|
||||
+/*
|
||||
* Freezer-friendly wrappers around wait_event_interruptible(),
|
||||
* wait_event_killable() and wait_event_interruptible_timeout(), originally
|
||||
* defined in <linux/wait.h>
|
||||
@@ -194,6 +217,11 @@ static inline int freezer_should_skip(struct task_struct *p) { return 0; }
|
||||
static inline void set_freezable(void) {}
|
||||
static inline void set_freezable_with_signal(void) {}
|
||||
|
||||
+#define freezable_schedule() schedule()
|
||||
+
|
||||
+#define freezable_schedule_timeout_killable(timeout) \
|
||||
+ schedule_timeout_killable(timeout)
|
||||
+
|
||||
#define wait_event_freezable(wq, condition) \
|
||||
wait_event_interruptible(wq, condition)
|
||||
|
||||
--- a/net/sunrpc/sched.c
|
||||
+++ a/net/sunrpc/sched.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/smp.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mutex.h>
|
||||
+#include <linux/freezer.h>
|
||||
|
||||
#include <linux/sunrpc/clnt.h>
|
||||
|
||||
@@ -231,7 +232,7 @@ static int rpc_wait_bit_killable(void *word)
|
||||
{
|
||||
if (fatal_signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
- schedule();
|
||||
+ freezable_schedule();
|
||||
return 0;
|
||||
}
|
||||
|
||||
include/linux/freezer.h | 21 ++++++++++++++++++---
|
||||
1 files changed, 18 insertions(+), 3 deletions(-)
|
||||
--- a/include/linux/freezer.h
|
||||
+++ a/include/linux/freezer.h
|
||||
@@ -141,18 +141,33 @@ static inline void set_freezable_with_signal(void)
|
||||
* while in this function.
|
||||
*/
|
||||
|
||||
-/* Like schedule(), but should not block the freezer. */
|
||||
+/*
|
||||
+ * Like schedule(), but should not block the freezer. It may return immediately
|
||||
+ * if it ends up racing with the freezer. Callers must be able to deal with
|
||||
+ * spurious wakeups.
|
||||
+ */
|
||||
#define freezable_schedule() \
|
||||
({ \
|
||||
freezer_do_not_count(); \
|
||||
- schedule(); \
|
||||
+ if (!try_to_freeze()) \
|
||||
+ schedule(); \
|
||||
freezer_count(); \
|
||||
})
|
||||
|
||||
-/* Like schedule_timeout_killable(), but should not block the freezer. */
|
||||
+/*
|
||||
+ * Like schedule_timeout_killable(), but should not block the freezer. It may
|
||||
+ * end up returning immediately if it ends up racing with the freezer. Callers
|
||||
+ * must be able to deal with the loose wakeup timing that can occur when the
|
||||
+ * freezer races in. When that occurs, this function will return the timeout
|
||||
+ * value instead of 0.
|
||||
+ */
|
||||
#define freezable_schedule_timeout_killable(timeout) \
|
||||
({ \
|
||||
freezer_do_not_count(); \
|
||||
+ if (try_to_freeze()) { \
|
||||
+ freezer_count(); \
|
||||
+ return timeout; \
|
||||
+ } \
|
||||
schedule_timeout_killable(timeout); \
|
||||
freezer_count(); \
|
||||
})
|
@ -1,118 +0,0 @@
|
||||
From: Andy Adamson <andros@xxxxxxxxxx>
|
||||
|
||||
The NFSv4 bitmap size is unbounded: a server can return an arbitrary
|
||||
sized bitmap in an FATTR4_WORD0_ACL request. Replace using the
|
||||
nfs4_fattr_bitmap_maxsz as a guess to the maximum bitmask returned by a server
|
||||
with the inclusion of the bitmap (xdr length plus bitmasks) and the acl data
|
||||
xdr length to the (cached) acl page data.
|
||||
|
||||
This is a general solution to commit e5012d1f "NFSv4.1: update
|
||||
nfs4_fattr_bitmap_maxsz" and fixes hitting a BUG_ON in xdr_shrink_bufhead
|
||||
when getting ACLs.
|
||||
|
||||
Cc:stable@xxxxxxxxxx
|
||||
Signed-off-by: Andy Adamson <andros@xxxxxxxxxx>
|
||||
---
|
||||
fs/nfs/nfs4proc.c | 20 ++++++++++++++++++--
|
||||
fs/nfs/nfs4xdr.c | 15 ++++++++++++---
|
||||
2 files changed, 30 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
|
||||
index deb88d9..97014dd 100644
|
||||
--- a/fs/nfs/nfs4proc.c
|
||||
+++ b/fs/nfs/nfs4proc.c
|
||||
@@ -3671,6 +3671,22 @@ static void nfs4_zap_acl_attr(struct inode *inode)
|
||||
nfs4_set_cached_acl(inode, NULL);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * The bitmap xdr length, bitmasks, and the attr xdr length are stored in
|
||||
+ * the acl cache to handle variable length bitmasks. Just copy the acl data.
|
||||
+ */
|
||||
+static void nfs4_copy_acl(char *buf, char *acl_data, size_t acl_len)
|
||||
+{
|
||||
+ __be32 *q, *p = (__be32 *)acl_data;
|
||||
+ int32_t len;
|
||||
+
|
||||
+ len = be32_to_cpup(p); /* number of bitmasks */
|
||||
+ len += 2; /* add words for bitmap and attr xdr len */
|
||||
+ q = p + len;
|
||||
+ len = len << 2; /* convert to bytes for acl_len math */
|
||||
+ memcpy(buf, (char *)q, acl_len - len);
|
||||
+}
|
||||
+
|
||||
static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen)
|
||||
{
|
||||
struct nfs_inode *nfsi = NFS_I(inode);
|
||||
@@ -3688,7 +3704,7 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_
|
||||
ret = -ERANGE; /* see getxattr(2) man page */
|
||||
if (acl->len > buflen)
|
||||
goto out;
|
||||
- memcpy(buf, acl->data, acl->len);
|
||||
+ nfs4_copy_acl(buf, acl->data, acl->len);
|
||||
out_len:
|
||||
ret = acl->len;
|
||||
out:
|
||||
@@ -3763,7 +3779,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
|
||||
if (res.acl_len > buflen)
|
||||
goto out_free;
|
||||
if (localpage)
|
||||
- memcpy(buf, resp_buf, res.acl_len);
|
||||
+ nfs4_copy_acl(buf, resp_buf, res.acl_len);
|
||||
}
|
||||
ret = res.acl_len;
|
||||
out_free:
|
||||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
|
||||
index f9fd96d..9c07380 100644
|
||||
--- a/fs/nfs/nfs4xdr.c
|
||||
+++ b/fs/nfs/nfs4xdr.c
|
||||
@@ -2513,7 +2513,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
|
||||
encode_compound_hdr(xdr, req, &hdr);
|
||||
encode_sequence(xdr, &args->seq_args, &hdr);
|
||||
encode_putfh(xdr, args->fh, &hdr);
|
||||
- replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1;
|
||||
+ replen = hdr.replen + op_decode_hdr_maxsz + 1;
|
||||
encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
|
||||
|
||||
xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
|
||||
@@ -4955,7 +4955,7 @@ decode_restorefh(struct xdr_stream *xdr)
|
||||
static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
|
||||
size_t *acl_len)
|
||||
{
|
||||
- __be32 *savep;
|
||||
+ __be32 *savep, *bm_p;
|
||||
uint32_t attrlen,
|
||||
bitmap[3] = {0};
|
||||
struct kvec *iov = req->rq_rcv_buf.head;
|
||||
@@ -4964,6 +4964,7 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
|
||||
*acl_len = 0;
|
||||
if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
|
||||
goto out;
|
||||
+ bm_p = xdr->p;
|
||||
if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
|
||||
goto out;
|
||||
if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
|
||||
@@ -4972,12 +4973,20 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
|
||||
if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
|
||||
return -EIO;
|
||||
if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
|
||||
- size_t hdrlen;
|
||||
+ size_t hdrlen, len;
|
||||
u32 recvd;
|
||||
|
||||
+ /*The bitmap (xdr len + bitmasks) and the attr xdr len words
|
||||
+ * are stored with the acl data to handle the problem of
|
||||
+ * variable length bitmasks.*/
|
||||
+ xdr->p = bm_p;
|
||||
+ len = be32_to_cpup(bm_p);
|
||||
+ len += 2; /* add bitmap and attr xdr len words */
|
||||
+
|
||||
/* We ignore &savep and don't do consistency checks on
|
||||
* the attr length. Let userspace figure it out.... */
|
||||
hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
|
||||
+ attrlen += len << 2; /* attrlen is in bytes */
|
||||
recvd = req->rq_rcv_buf.len - hdrlen;
|
||||
if (attrlen > recvd) {
|
||||
dprintk("NFS: server cheating in getattr"
|
||||
--
|
||||
1.7.6.4
|
@ -1,287 +0,0 @@
|
||||
Path: news.gmane.org!not-for-mail
|
||||
From: Matthew Garrett <mjg@redhat.com>
|
||||
Newsgroups: gmane.linux.acpi.devel,gmane.linux.kernel.pci,gmane.linux.kernel
|
||||
Subject: [PATCH] pci: Rework ASPM disable code
|
||||
Date: Thu, 10 Nov 2011 16:38:33 -0500
|
||||
Lines: 232
|
||||
Approved: news@gmane.org
|
||||
Message-ID: <1320961113-5050-1-git-send-email-mjg@redhat.com>
|
||||
NNTP-Posting-Host: lo.gmane.org
|
||||
X-Trace: dough.gmane.org 1320961145 13112 80.91.229.12 (10 Nov 2011 21:39:05 GMT)
|
||||
X-Complaints-To: usenet@dough.gmane.org
|
||||
NNTP-Posting-Date: Thu, 10 Nov 2011 21:39:05 +0000 (UTC)
|
||||
Cc: linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org,
|
||||
linux-kernel@vger.kernel.org, Matthew Garrett <mjg@redhat.com>
|
||||
To: jbarnes@virtuousgeek.org
|
||||
Original-X-From: linux-acpi-owner@vger.kernel.org Thu Nov 10 22:38:57 2011
|
||||
Return-path: <linux-acpi-owner@vger.kernel.org>
|
||||
Envelope-to: glad-acpi-devel@lo.gmane.org
|
||||
Original-Received: from vger.kernel.org ([209.132.180.67])
|
||||
by lo.gmane.org with esmtp (Exim 4.69)
|
||||
(envelope-from <linux-acpi-owner@vger.kernel.org>)
|
||||
id 1ROcKm-0003jN-CL
|
||||
for glad-acpi-devel@lo.gmane.org; Thu, 10 Nov 2011 22:38:56 +0100
|
||||
Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
||||
id S1751342Ab1KJViu (ORCPT <rfc822;glad-acpi-devel@m.gmane.org>);
|
||||
Thu, 10 Nov 2011 16:38:50 -0500
|
||||
Original-Received: from mx1.redhat.com ([209.132.183.28]:32030 "EHLO mx1.redhat.com"
|
||||
rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
|
||||
id S1750805Ab1KJVit (ORCPT <rfc822;linux-acpi@vger.kernel.org>);
|
||||
Thu, 10 Nov 2011 16:38:49 -0500
|
||||
Original-Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22])
|
||||
by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id pAALcmdw013333
|
||||
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK);
|
||||
Thu, 10 Nov 2011 16:38:49 -0500
|
||||
Original-Received: from cavan.codon.org.uk (ovpn-113-157.phx2.redhat.com [10.3.113.157])
|
||||
by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id pAALclkW022022
|
||||
(version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO);
|
||||
Thu, 10 Nov 2011 16:38:48 -0500
|
||||
Original-Received: from 209-6-41-104.c3-0.smr-ubr1.sbo-smr.ma.cable.rcn.com ([209.6.41.104] helo=localhost.localdomain)
|
||||
by cavan.codon.org.uk with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.72)
|
||||
(envelope-from <mjg@redhat.com>)
|
||||
id 1ROcKa-0000F4-E4; Thu, 10 Nov 2011 21:38:44 +0000
|
||||
X-SA-Do-Not-Run: Yes
|
||||
X-SA-Exim-Connect-IP: 209.6.41.104
|
||||
X-SA-Exim-Mail-From: mjg@redhat.com
|
||||
X-SA-Exim-Scanned: No (on cavan.codon.org.uk); SAEximRunCond expanded to false
|
||||
X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22
|
||||
Original-Sender: linux-acpi-owner@vger.kernel.org
|
||||
Precedence: bulk
|
||||
List-ID: <linux-acpi.vger.kernel.org>
|
||||
X-Mailing-List: linux-acpi@vger.kernel.org
|
||||
Xref: news.gmane.org gmane.linux.acpi.devel:51182 gmane.linux.kernel.pci:12503 gmane.linux.kernel:1214427
|
||||
Archived-At: <http://permalink.gmane.org/gmane.linux.acpi.devel/51182>
|
||||
|
||||
Right now we forcibly clear ASPM state on all devices if the BIOS indicates
|
||||
that the feature isn't supported. Based on the Microsoft presentation
|
||||
"PCI Express In Depth for Windows Vista and Beyond", I'm starting to think
|
||||
that this may be an error. The implication is that unless the platform
|
||||
grants full control via _OSC, Windows will not touch any PCIe features -
|
||||
including ASPM. In that case clearing ASPM state would be an error unless
|
||||
the platform has granted us that control.
|
||||
|
||||
This patch reworks the ASPM disabling code such that the actual clearing
|
||||
of state is triggered by a successful handoff of PCIe control to the OS.
|
||||
The general ASPM code undergoes some changes in order to ensure that the
|
||||
ability to clear the bits isn't overridden by ASPM having already been
|
||||
disabled. Further, this theoretically now allows for situations where
|
||||
only a subset of PCIe roots hand over control, leaving the others in the
|
||||
BIOS state.
|
||||
|
||||
It's difficult to know for sure that this is the right thing to do -
|
||||
there's zero public documentation on the interaction between all of these
|
||||
components. But enough vendors enable ASPM on platforms and then set this
|
||||
bit that it seems likely that they're expecting the OS to leave them alone.
|
||||
|
||||
Measured to save around 5W on an idle Thinkpad X220.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg@redhat.com>
|
||||
---
|
||||
drivers/acpi/pci_root.c | 7 +++++
|
||||
drivers/pci/pci-acpi.c | 1 -
|
||||
drivers/pci/pcie/aspm.c | 58 +++++++++++++++++++++++++++++----------------
|
||||
include/linux/pci-aspm.h | 4 +-
|
||||
4 files changed, 46 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
|
||||
index 2672c79..7aff631 100644
|
||||
--- a/drivers/acpi/pci_root.c
|
||||
+++ b/drivers/acpi/pci_root.c
|
||||
@@ -596,6 +596,13 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
dev_info(root->bus->bridge,
|
||||
"ACPI _OSC control (0x%02x) granted\n", flags);
|
||||
+ if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
|
||||
+ /*
|
||||
+ * We have ASPM control, but the FADT indicates
|
||||
+ * that it's unsupported. Clear it.
|
||||
+ */
|
||||
+ pcie_clear_aspm(root->bus);
|
||||
+ }
|
||||
} else {
|
||||
dev_info(root->bus->bridge,
|
||||
"ACPI _OSC request failed (%s), "
|
||||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
|
||||
index 4ecb640..c8e7585 100644
|
||||
--- a/drivers/pci/pci-acpi.c
|
||||
+++ b/drivers/pci/pci-acpi.c
|
||||
@@ -395,7 +395,6 @@ static int __init acpi_pci_init(void)
|
||||
|
||||
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
|
||||
printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
|
||||
- pcie_clear_aspm();
|
||||
pcie_no_aspm();
|
||||
}
|
||||
|
||||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
|
||||
index cbfbab1..1cfbf22 100644
|
||||
--- a/drivers/pci/pcie/aspm.c
|
||||
+++ b/drivers/pci/pcie/aspm.c
|
||||
@@ -68,7 +68,7 @@ struct pcie_link_state {
|
||||
struct aspm_latency acceptable[8];
|
||||
};
|
||||
|
||||
-static int aspm_disabled, aspm_force, aspm_clear_state;
|
||||
+static int aspm_disabled, aspm_force;
|
||||
static bool aspm_support_enabled = true;
|
||||
static DEFINE_MUTEX(aspm_lock);
|
||||
static LIST_HEAD(link_list);
|
||||
@@ -500,9 +500,6 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
|
||||
int pos;
|
||||
u32 reg32;
|
||||
|
||||
- if (aspm_clear_state)
|
||||
- return -EINVAL;
|
||||
-
|
||||
/*
|
||||
* Some functions in a slot might not all be PCIe functions,
|
||||
* very strange. Disable ASPM for the whole slot
|
||||
@@ -574,9 +571,6 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
|
||||
pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
|
||||
return;
|
||||
|
||||
- if (aspm_disabled && !aspm_clear_state)
|
||||
- return;
|
||||
-
|
||||
/* VIA has a strange chipset, root port is under a bridge */
|
||||
if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
|
||||
pdev->bus->self)
|
||||
@@ -608,7 +602,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
|
||||
* the BIOS's expectation, we'll do so once pci_enable_device() is
|
||||
* called.
|
||||
*/
|
||||
- if (aspm_policy != POLICY_POWERSAVE || aspm_clear_state) {
|
||||
+ if (aspm_policy != POLICY_POWERSAVE) {
|
||||
pcie_config_aspm_path(link);
|
||||
pcie_set_clkpm(link, policy_to_clkpm_state(link));
|
||||
}
|
||||
@@ -649,8 +643,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
|
||||
struct pci_dev *parent = pdev->bus->self;
|
||||
struct pcie_link_state *link, *root, *parent_link;
|
||||
|
||||
- if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||
|
||||
- !parent || !parent->link_state)
|
||||
+ if (!pci_is_pcie(pdev) || !parent || !parent->link_state)
|
||||
return;
|
||||
if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
|
||||
(parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
|
||||
@@ -734,13 +727,18 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
|
||||
* pci_disable_link_state - disable pci device's link state, so the link will
|
||||
* never enter specific states
|
||||
*/
|
||||
-static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
|
||||
+static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem,
|
||||
+ bool force)
|
||||
{
|
||||
struct pci_dev *parent = pdev->bus->self;
|
||||
struct pcie_link_state *link;
|
||||
|
||||
- if (aspm_disabled || !pci_is_pcie(pdev))
|
||||
+ if (aspm_disabled && !force)
|
||||
+ return;
|
||||
+
|
||||
+ if (!pci_is_pcie(pdev))
|
||||
return;
|
||||
+
|
||||
if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)
|
||||
parent = pdev;
|
||||
@@ -768,16 +766,31 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
|
||||
|
||||
void pci_disable_link_state_locked(struct pci_dev *pdev, int state)
|
||||
{
|
||||
- __pci_disable_link_state(pdev, state, false);
|
||||
+ __pci_disable_link_state(pdev, state, false, false);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_disable_link_state_locked);
|
||||
|
||||
void pci_disable_link_state(struct pci_dev *pdev, int state)
|
||||
{
|
||||
- __pci_disable_link_state(pdev, state, true);
|
||||
+ __pci_disable_link_state(pdev, state, true, false);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_disable_link_state);
|
||||
|
||||
+void pcie_clear_aspm(struct pci_bus *bus)
|
||||
+{
|
||||
+ struct pci_dev *child;
|
||||
+
|
||||
+ /*
|
||||
+ * Clear any ASPM setup that the firmware has carried out on this bus
|
||||
+ */
|
||||
+ list_for_each_entry(child, &bus->devices, bus_list) {
|
||||
+ __pci_disable_link_state(child, PCIE_LINK_STATE_L0S |
|
||||
+ PCIE_LINK_STATE_L1 |
|
||||
+ PCIE_LINK_STATE_CLKPM,
|
||||
+ false, true);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
|
||||
{
|
||||
int i;
|
||||
@@ -935,6 +948,7 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
|
||||
static int __init pcie_aspm_disable(char *str)
|
||||
{
|
||||
if (!strcmp(str, "off")) {
|
||||
+ aspm_policy = POLICY_DEFAULT;
|
||||
aspm_disabled = 1;
|
||||
aspm_support_enabled = false;
|
||||
printk(KERN_INFO "PCIe ASPM is disabled\n");
|
||||
@@ -947,16 +961,18 @@ static int __init pcie_aspm_disable(char *str)
|
||||
|
||||
__setup("pcie_aspm=", pcie_aspm_disable);
|
||||
|
||||
-void pcie_clear_aspm(void)
|
||||
-{
|
||||
- if (!aspm_force)
|
||||
- aspm_clear_state = 1;
|
||||
-}
|
||||
-
|
||||
void pcie_no_aspm(void)
|
||||
{
|
||||
- if (!aspm_force)
|
||||
+ /*
|
||||
+ * Disabling ASPM is intended to prevent the kernel from modifying
|
||||
+ * existing hardware state, not to clear existing state. To that end:
|
||||
+ * (a) set policy to POLICY_DEFAULT in order to avoid changing state
|
||||
+ * (b) prevent userspace from changing policy
|
||||
+ */
|
||||
+ if (!aspm_force) {
|
||||
+ aspm_policy = POLICY_DEFAULT;
|
||||
aspm_disabled = 1;
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
|
||||
index 7cea7b6..c832014 100644
|
||||
--- a/include/linux/pci-aspm.h
|
||||
+++ b/include/linux/pci-aspm.h
|
||||
@@ -29,7 +29,7 @@ extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
|
||||
extern void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
|
||||
extern void pci_disable_link_state(struct pci_dev *pdev, int state);
|
||||
extern void pci_disable_link_state_locked(struct pci_dev *pdev, int state);
|
||||
-extern void pcie_clear_aspm(void);
|
||||
+extern void pcie_clear_aspm(struct pci_bus *bus);
|
||||
extern void pcie_no_aspm(void);
|
||||
#else
|
||||
static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
|
||||
@@ -47,7 +47,7 @@ static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
|
||||
static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
|
||||
{
|
||||
}
|
||||
-static inline void pcie_clear_aspm(void)
|
||||
+static inline void pcie_clear_aspm(struct pci_bus *bus)
|
||||
{
|
||||
}
|
||||
static inline void pcie_no_aspm(void)
|
||||
--
|
||||
1.7.7.1
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
@ -1,268 +0,0 @@
|
||||
From e268337dfe26dfc7efd422a804dbb27977a3cccc Mon Sep 17 00:00:00 2001
|
||||
From: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Date: Tue, 17 Jan 2012 15:21:19 -0800
|
||||
Subject: [PATCH] proc: clean up and fix /proc/<pid>/mem handling
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Jüri Aedla reported that the /proc/<pid>/mem handling really isn't very
|
||||
robust, and it also doesn't match the permission checking of any of the
|
||||
other related files.
|
||||
|
||||
This changes it to do the permission checks at open time, and instead of
|
||||
tracking the process, it tracks the VM at the time of the open. That
|
||||
simplifies the code a lot, but does mean that if you hold the file
|
||||
descriptor open over an execve(), you'll continue to read from the _old_
|
||||
VM.
|
||||
|
||||
That is different from our previous behavior, but much simpler. If
|
||||
somebody actually finds a load where this matters, we'll need to revert
|
||||
this commit.
|
||||
|
||||
I suspect that nobody will ever notice - because the process mapping
|
||||
addresses will also have changed as part of the execve. So you cannot
|
||||
actually usefully access the fd across a VM change simply because all
|
||||
the offsets for IO would have changed too.
|
||||
|
||||
Reported-by: Jüri Aedla <asd@ut.ee>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
fs/proc/base.c | 145 +++++++++++++++-----------------------------------------
|
||||
1 files changed, 39 insertions(+), 106 deletions(-)
|
||||
|
||||
diff --git a/fs/proc/base.c b/fs/proc/base.c
|
||||
index 5485a53..662ddf2 100644
|
||||
--- a/fs/proc/base.c
|
||||
+++ b/fs/proc/base.c
|
||||
@@ -198,65 +198,7 @@ static int proc_root_link(struct dentry *dentry, struct path *path)
|
||||
return result;
|
||||
}
|
||||
|
||||
-static struct mm_struct *__check_mem_permission(struct task_struct *task)
|
||||
-{
|
||||
- struct mm_struct *mm;
|
||||
-
|
||||
- mm = get_task_mm(task);
|
||||
- if (!mm)
|
||||
- return ERR_PTR(-EINVAL);
|
||||
-
|
||||
- /*
|
||||
- * A task can always look at itself, in case it chooses
|
||||
- * to use system calls instead of load instructions.
|
||||
- */
|
||||
- if (task == current)
|
||||
- return mm;
|
||||
-
|
||||
- /*
|
||||
- * If current is actively ptrace'ing, and would also be
|
||||
- * permitted to freshly attach with ptrace now, permit it.
|
||||
- */
|
||||
- if (task_is_stopped_or_traced(task)) {
|
||||
- int match;
|
||||
- rcu_read_lock();
|
||||
- match = (ptrace_parent(task) == current);
|
||||
- rcu_read_unlock();
|
||||
- if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))
|
||||
- return mm;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * No one else is allowed.
|
||||
- */
|
||||
- mmput(mm);
|
||||
- return ERR_PTR(-EPERM);
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * If current may access user memory in @task return a reference to the
|
||||
- * corresponding mm, otherwise ERR_PTR.
|
||||
- */
|
||||
-static struct mm_struct *check_mem_permission(struct task_struct *task)
|
||||
-{
|
||||
- struct mm_struct *mm;
|
||||
- int err;
|
||||
-
|
||||
- /*
|
||||
- * Avoid racing if task exec's as we might get a new mm but validate
|
||||
- * against old credentials.
|
||||
- */
|
||||
- err = mutex_lock_killable(&task->signal->cred_guard_mutex);
|
||||
- if (err)
|
||||
- return ERR_PTR(err);
|
||||
-
|
||||
- mm = __check_mem_permission(task);
|
||||
- mutex_unlock(&task->signal->cred_guard_mutex);
|
||||
-
|
||||
- return mm;
|
||||
-}
|
||||
-
|
||||
-struct mm_struct *mm_for_maps(struct task_struct *task)
|
||||
+static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
|
||||
{
|
||||
struct mm_struct *mm;
|
||||
int err;
|
||||
@@ -267,7 +209,7 @@ struct mm_struct *mm_for_maps(struct task_struct *task)
|
||||
|
||||
mm = get_task_mm(task);
|
||||
if (mm && mm != current->mm &&
|
||||
- !ptrace_may_access(task, PTRACE_MODE_READ)) {
|
||||
+ !ptrace_may_access(task, mode)) {
|
||||
mmput(mm);
|
||||
mm = ERR_PTR(-EACCES);
|
||||
}
|
||||
@@ -276,6 +218,11 @@ struct mm_struct *mm_for_maps(struct task_struct *task)
|
||||
return mm;
|
||||
}
|
||||
|
||||
+struct mm_struct *mm_for_maps(struct task_struct *task)
|
||||
+{
|
||||
+ return mm_access(task, PTRACE_MODE_READ);
|
||||
+}
|
||||
+
|
||||
static int proc_pid_cmdline(struct task_struct *task, char * buffer)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -752,38 +699,39 @@ static const struct file_operations proc_single_file_operations = {
|
||||
|
||||
static int mem_open(struct inode* inode, struct file* file)
|
||||
{
|
||||
- file->private_data = (void*)((long)current->self_exec_id);
|
||||
+ struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
|
||||
+ struct mm_struct *mm;
|
||||
+
|
||||
+ if (!task)
|
||||
+ return -ESRCH;
|
||||
+
|
||||
+ mm = mm_access(task, PTRACE_MODE_ATTACH);
|
||||
+ put_task_struct(task);
|
||||
+
|
||||
+ if (IS_ERR(mm))
|
||||
+ return PTR_ERR(mm);
|
||||
+
|
||||
/* OK to pass negative loff_t, we can catch out-of-range */
|
||||
file->f_mode |= FMODE_UNSIGNED_OFFSET;
|
||||
+ file->private_data = mm;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t mem_read(struct file * file, char __user * buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
- struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
|
||||
+ int ret;
|
||||
char *page;
|
||||
unsigned long src = *ppos;
|
||||
- int ret = -ESRCH;
|
||||
- struct mm_struct *mm;
|
||||
+ struct mm_struct *mm = file->private_data;
|
||||
|
||||
- if (!task)
|
||||
- goto out_no_task;
|
||||
+ if (!mm)
|
||||
+ return 0;
|
||||
|
||||
- ret = -ENOMEM;
|
||||
page = (char *)__get_free_page(GFP_TEMPORARY);
|
||||
if (!page)
|
||||
- goto out;
|
||||
-
|
||||
- mm = check_mem_permission(task);
|
||||
- ret = PTR_ERR(mm);
|
||||
- if (IS_ERR(mm))
|
||||
- goto out_free;
|
||||
-
|
||||
- ret = -EIO;
|
||||
-
|
||||
- if (file->private_data != (void*)((long)current->self_exec_id))
|
||||
- goto out_put;
|
||||
+ return -ENOMEM;
|
||||
|
||||
ret = 0;
|
||||
|
||||
@@ -810,13 +758,7 @@ static ssize_t mem_read(struct file * file, char __user * buf,
|
||||
}
|
||||
*ppos = src;
|
||||
|
||||
-out_put:
|
||||
- mmput(mm);
|
||||
-out_free:
|
||||
free_page((unsigned long) page);
|
||||
-out:
|
||||
- put_task_struct(task);
|
||||
-out_no_task:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -825,27 +767,15 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
|
||||
{
|
||||
int copied;
|
||||
char *page;
|
||||
- struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
|
||||
unsigned long dst = *ppos;
|
||||
- struct mm_struct *mm;
|
||||
+ struct mm_struct *mm = file->private_data;
|
||||
|
||||
- copied = -ESRCH;
|
||||
- if (!task)
|
||||
- goto out_no_task;
|
||||
+ if (!mm)
|
||||
+ return 0;
|
||||
|
||||
- copied = -ENOMEM;
|
||||
page = (char *)__get_free_page(GFP_TEMPORARY);
|
||||
if (!page)
|
||||
- goto out_task;
|
||||
-
|
||||
- mm = check_mem_permission(task);
|
||||
- copied = PTR_ERR(mm);
|
||||
- if (IS_ERR(mm))
|
||||
- goto out_free;
|
||||
-
|
||||
- copied = -EIO;
|
||||
- if (file->private_data != (void *)((long)current->self_exec_id))
|
||||
- goto out_mm;
|
||||
+ return -ENOMEM;
|
||||
|
||||
copied = 0;
|
||||
while (count > 0) {
|
||||
@@ -869,13 +799,7 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
|
||||
}
|
||||
*ppos = dst;
|
||||
|
||||
-out_mm:
|
||||
- mmput(mm);
|
||||
-out_free:
|
||||
free_page((unsigned long) page);
|
||||
-out_task:
|
||||
- put_task_struct(task);
|
||||
-out_no_task:
|
||||
return copied;
|
||||
}
|
||||
|
||||
@@ -895,11 +819,20 @@ loff_t mem_lseek(struct file *file, loff_t offset, int orig)
|
||||
return file->f_pos;
|
||||
}
|
||||
|
||||
+static int mem_release(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ struct mm_struct *mm = file->private_data;
|
||||
+
|
||||
+ mmput(mm);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct file_operations proc_mem_operations = {
|
||||
.llseek = mem_lseek,
|
||||
.read = mem_read,
|
||||
.write = mem_write,
|
||||
.open = mem_open,
|
||||
+ .release = mem_release,
|
||||
};
|
||||
|
||||
static ssize_t environ_read(struct file *file, char __user *buf,
|
||||
--
|
||||
1.7.7.5
|
||||
|
@ -1,44 +0,0 @@
|
||||
From a2ef990ab5a6705a356d146dd773a3b359787497 Mon Sep 17 00:00:00 2001
|
||||
From: Xiaotian Feng <xtfeng@gmail.com>
|
||||
Date: Thu, 12 Jan 2012 17:17:08 -0800
|
||||
Subject: [PATCH] proc: fix null pointer deref in proc_pid_permission()
|
||||
|
||||
get_proc_task() can fail to search the task and return NULL,
|
||||
put_task_struct() will then bomb the kernel with following oops:
|
||||
|
||||
BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
|
||||
IP: [<ffffffff81217d34>] proc_pid_permission+0x64/0xe0
|
||||
PGD 112075067 PUD 112814067 PMD 0
|
||||
Oops: 0002 [#1] PREEMPT SMP
|
||||
|
||||
This is a regression introduced by commit 0499680a ("procfs: add hidepid=
|
||||
and gid= mount options"). The kernel should return -ESRCH if
|
||||
get_proc_task() failed.
|
||||
|
||||
Signed-off-by: Xiaotian Feng <dannyfeng@tencent.com>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: Vasiliy Kulikov <segoon@openwall.com>
|
||||
Cc: Stephen Wilson <wilsons@start.ca>
|
||||
Acked-by: David Rientjes <rientjes@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
fs/proc/base.c | 2 ++
|
||||
1 files changed, 2 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/fs/proc/base.c b/fs/proc/base.c
|
||||
index 8173dfd..5485a53 100644
|
||||
--- a/fs/proc/base.c
|
||||
+++ b/fs/proc/base.c
|
||||
@@ -654,6 +654,8 @@ static int proc_pid_permission(struct inode *inode, int mask)
|
||||
bool has_perms;
|
||||
|
||||
task = get_proc_task(inode);
|
||||
+ if (!task)
|
||||
+ return -ESRCH;
|
||||
has_perms = has_pid_permissions(pid, task, 1);
|
||||
put_task_struct(task);
|
||||
|
||||
--
|
||||
1.7.7.5
|
||||
|
@ -1,342 +0,0 @@
|
||||
From 0499680a42141d86417a8fbaa8c8db806bea1201 Mon Sep 17 00:00:00 2001
|
||||
From: Vasiliy Kulikov <segooon@gmail.com>
|
||||
Date: Tue, 10 Jan 2012 15:11:31 -0800
|
||||
Subject: [PATCH] procfs: add hidepid= and gid= mount options
|
||||
|
||||
Add support for mount options to restrict access to /proc/PID/
|
||||
directories. The default backward-compatible "relaxed" behaviour is left
|
||||
untouched.
|
||||
|
||||
The first mount option is called "hidepid" and its value defines how much
|
||||
info about processes we want to be available for non-owners:
|
||||
|
||||
hidepid=0 (default) means the old behavior - anybody may read all
|
||||
world-readable /proc/PID/* files.
|
||||
|
||||
hidepid=1 means users may not access any /proc/<pid>/ directories, but
|
||||
their own. Sensitive files like cmdline, sched*, status are now protected
|
||||
against other users. As permission checking done in proc_pid_permission()
|
||||
and files' permissions are left untouched, programs expecting specific
|
||||
files' modes are not confused.
|
||||
|
||||
hidepid=2 means hidepid=1 plus all /proc/PID/ will be invisible to other
|
||||
users. It doesn't mean that it hides whether a process exists (it can be
|
||||
learned by other means, e.g. by kill -0 $PID), but it hides process' euid
|
||||
and egid. It compicates intruder's task of gathering info about running
|
||||
processes, whether some daemon runs with elevated privileges, whether
|
||||
another user runs some sensitive program, whether other users run any
|
||||
program at all, etc.
|
||||
|
||||
gid=XXX defines a group that will be able to gather all processes' info
|
||||
(as in hidepid=0 mode). This group should be used instead of putting
|
||||
nonroot user in sudoers file or something. However, untrusted users (like
|
||||
daemons, etc.) which are not supposed to monitor the tasks in the whole
|
||||
system should not be added to the group.
|
||||
|
||||
hidepid=1 or higher is designed to restrict access to procfs files, which
|
||||
might reveal some sensitive private information like precise keystrokes
|
||||
timings:
|
||||
|
||||
http://www.openwall.com/lists/oss-security/2011/11/05/3
|
||||
|
||||
hidepid=1/2 doesn't break monitoring userspace tools. ps, top, pgrep, and
|
||||
conky gracefully handle EPERM/ENOENT and behave as if the current user is
|
||||
the only user running processes. pstree shows the process subtree which
|
||||
contains "pstree" process.
|
||||
|
||||
Note: the patch doesn't deal with setuid/setgid issues of keeping
|
||||
preopened descriptors of procfs files (like
|
||||
https://lkml.org/lkml/2011/2/7/368). We rely on that the leaked
|
||||
information like the scheduling counters of setuid apps doesn't threaten
|
||||
anybody's privacy - only the user started the setuid program may read the
|
||||
counters.
|
||||
|
||||
Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
|
||||
Cc: Alexey Dobriyan <adobriyan@gmail.com>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: Randy Dunlap <rdunlap@xenotime.net>
|
||||
Cc: "H. Peter Anvin" <hpa@zytor.com>
|
||||
Cc: Greg KH <greg@kroah.com>
|
||||
Cc: Theodore Tso <tytso@MIT.EDU>
|
||||
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
|
||||
Cc: James Morris <jmorris@namei.org>
|
||||
Cc: Oleg Nesterov <oleg@redhat.com>
|
||||
Cc: Hugh Dickins <hughd@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
Documentation/filesystems/proc.txt | 39 ++++++++++++++++++++
|
||||
fs/proc/base.c | 69 +++++++++++++++++++++++++++++++++++-
|
||||
fs/proc/inode.c | 8 ++++
|
||||
fs/proc/root.c | 21 +++++++++--
|
||||
include/linux/pid_namespace.h | 2 +
|
||||
5 files changed, 135 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
|
||||
index 0ec91f0..12fee13 100644
|
||||
--- a/Documentation/filesystems/proc.txt
|
||||
+++ b/Documentation/filesystems/proc.txt
|
||||
@@ -41,6 +41,8 @@ Table of Contents
|
||||
3.5 /proc/<pid>/mountinfo - Information about mounts
|
||||
3.6 /proc/<pid>/comm & /proc/<pid>/task/<tid>/comm
|
||||
|
||||
+ 4 Configuring procfs
|
||||
+ 4.1 Mount options
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Preface
|
||||
@@ -1542,3 +1544,40 @@ a task to set its own or one of its thread siblings comm value. The comm value
|
||||
is limited in size compared to the cmdline value, so writing anything longer
|
||||
then the kernel's TASK_COMM_LEN (currently 16 chars) will result in a truncated
|
||||
comm value.
|
||||
+
|
||||
+
|
||||
+------------------------------------------------------------------------------
|
||||
+Configuring procfs
|
||||
+------------------------------------------------------------------------------
|
||||
+
|
||||
+4.1 Mount options
|
||||
+---------------------
|
||||
+
|
||||
+The following mount options are supported:
|
||||
+
|
||||
+ hidepid= Set /proc/<pid>/ access mode.
|
||||
+ gid= Set the group authorized to learn processes information.
|
||||
+
|
||||
+hidepid=0 means classic mode - everybody may access all /proc/<pid>/ directories
|
||||
+(default).
|
||||
+
|
||||
+hidepid=1 means users may not access any /proc/<pid>/ directories but their
|
||||
+own. Sensitive files like cmdline, sched*, status are now protected against
|
||||
+other users. This makes it impossible to learn whether any user runs
|
||||
+specific program (given the program doesn't reveal itself by its behaviour).
|
||||
+As an additional bonus, as /proc/<pid>/cmdline is unaccessible for other users,
|
||||
+poorly written programs passing sensitive information via program arguments are
|
||||
+now protected against local eavesdroppers.
|
||||
+
|
||||
+hidepid=2 means hidepid=1 plus all /proc/<pid>/ will be fully invisible to other
|
||||
+users. It doesn't mean that it hides a fact whether a process with a specific
|
||||
+pid value exists (it can be learned by other means, e.g. by "kill -0 $PID"),
|
||||
+but it hides process' uid and gid, which may be learned by stat()'ing
|
||||
+/proc/<pid>/ otherwise. It greatly complicates an intruder's task of gathering
|
||||
+information about running processes, whether some daemon runs with elevated
|
||||
+privileges, whether other user runs some sensitive program, whether other users
|
||||
+run any program at all, etc.
|
||||
+
|
||||
+gid= defines a group authorized to learn processes information otherwise
|
||||
+prohibited by hidepid=. If you use some daemon like identd which needs to learn
|
||||
+information about processes information, just add identd to this group.
|
||||
diff --git a/fs/proc/base.c b/fs/proc/base.c
|
||||
index 4d755fe..8173dfd 100644
|
||||
--- a/fs/proc/base.c
|
||||
+++ b/fs/proc/base.c
|
||||
@@ -631,6 +631,50 @@ int proc_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * May current process learn task's sched/cmdline info (for hide_pid_min=1)
|
||||
+ * or euid/egid (for hide_pid_min=2)?
|
||||
+ */
|
||||
+static bool has_pid_permissions(struct pid_namespace *pid,
|
||||
+ struct task_struct *task,
|
||||
+ int hide_pid_min)
|
||||
+{
|
||||
+ if (pid->hide_pid < hide_pid_min)
|
||||
+ return true;
|
||||
+ if (in_group_p(pid->pid_gid))
|
||||
+ return true;
|
||||
+ return ptrace_may_access(task, PTRACE_MODE_READ);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int proc_pid_permission(struct inode *inode, int mask)
|
||||
+{
|
||||
+ struct pid_namespace *pid = inode->i_sb->s_fs_info;
|
||||
+ struct task_struct *task;
|
||||
+ bool has_perms;
|
||||
+
|
||||
+ task = get_proc_task(inode);
|
||||
+ has_perms = has_pid_permissions(pid, task, 1);
|
||||
+ put_task_struct(task);
|
||||
+
|
||||
+ if (!has_perms) {
|
||||
+ if (pid->hide_pid == 2) {
|
||||
+ /*
|
||||
+ * Let's make getdents(), stat(), and open()
|
||||
+ * consistent with each other. If a process
|
||||
+ * may not stat() a file, it shouldn't be seen
|
||||
+ * in procfs at all.
|
||||
+ */
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
+
|
||||
+ return -EPERM;
|
||||
+ }
|
||||
+ return generic_permission(inode, mask);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
static const struct inode_operations proc_def_inode_operations = {
|
||||
.setattr = proc_setattr,
|
||||
};
|
||||
@@ -1615,6 +1659,7 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
|
||||
struct inode *inode = dentry->d_inode;
|
||||
struct task_struct *task;
|
||||
const struct cred *cred;
|
||||
+ struct pid_namespace *pid = dentry->d_sb->s_fs_info;
|
||||
|
||||
generic_fillattr(inode, stat);
|
||||
|
||||
@@ -1623,6 +1668,14 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
|
||||
stat->gid = 0;
|
||||
task = pid_task(proc_pid(inode), PIDTYPE_PID);
|
||||
if (task) {
|
||||
+ if (!has_pid_permissions(pid, task, 2)) {
|
||||
+ rcu_read_unlock();
|
||||
+ /*
|
||||
+ * This doesn't prevent learning whether PID exists,
|
||||
+ * it only makes getattr() consistent with readdir().
|
||||
+ */
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
|
||||
task_dumpable(task)) {
|
||||
cred = __task_cred(task);
|
||||
@@ -3119,6 +3172,7 @@ static const struct inode_operations proc_tgid_base_inode_operations = {
|
||||
.lookup = proc_tgid_base_lookup,
|
||||
.getattr = pid_getattr,
|
||||
.setattr = proc_setattr,
|
||||
+ .permission = proc_pid_permission,
|
||||
};
|
||||
|
||||
static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
|
||||
@@ -3322,6 +3376,12 @@ static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldi
|
||||
proc_pid_instantiate, iter.task, NULL);
|
||||
}
|
||||
|
||||
+static int fake_filldir(void *buf, const char *name, int namelen,
|
||||
+ loff_t offset, u64 ino, unsigned d_type)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* for the /proc/ directory itself, after non-process stuff has been done */
|
||||
int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
|
||||
{
|
||||
@@ -3329,6 +3389,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
|
||||
struct task_struct *reaper;
|
||||
struct tgid_iter iter;
|
||||
struct pid_namespace *ns;
|
||||
+ filldir_t __filldir;
|
||||
|
||||
if (filp->f_pos >= PID_MAX_LIMIT + TGID_OFFSET)
|
||||
goto out_no_task;
|
||||
@@ -3350,8 +3411,13 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
|
||||
for (iter = next_tgid(ns, iter);
|
||||
iter.task;
|
||||
iter.tgid += 1, iter = next_tgid(ns, iter)) {
|
||||
+ if (has_pid_permissions(ns, iter.task, 2))
|
||||
+ __filldir = filldir;
|
||||
+ else
|
||||
+ __filldir = fake_filldir;
|
||||
+
|
||||
filp->f_pos = iter.tgid + TGID_OFFSET;
|
||||
- if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
|
||||
+ if (proc_pid_fill_cache(filp, dirent, __filldir, iter) < 0) {
|
||||
put_task_struct(iter.task);
|
||||
goto out;
|
||||
}
|
||||
@@ -3686,6 +3752,7 @@ static const struct inode_operations proc_task_inode_operations = {
|
||||
.lookup = proc_task_lookup,
|
||||
.getattr = proc_task_getattr,
|
||||
.setattr = proc_setattr,
|
||||
+ .permission = proc_pid_permission,
|
||||
};
|
||||
|
||||
static const struct file_operations proc_task_operations = {
|
||||
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
|
||||
index 27c762f..84fd323 100644
|
||||
--- a/fs/proc/inode.c
|
||||
+++ b/fs/proc/inode.c
|
||||
@@ -106,6 +106,14 @@ void __init proc_init_inodecache(void)
|
||||
|
||||
static int proc_show_options(struct seq_file *seq, struct vfsmount *vfs)
|
||||
{
|
||||
+ struct super_block *sb = vfs->mnt_sb;
|
||||
+ struct pid_namespace *pid = sb->s_fs_info;
|
||||
+
|
||||
+ if (pid->pid_gid)
|
||||
+ seq_printf(seq, ",gid=%lu", (unsigned long)pid->pid_gid);
|
||||
+ if (pid->hide_pid != 0)
|
||||
+ seq_printf(seq, ",hidepid=%u", pid->hide_pid);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/fs/proc/root.c b/fs/proc/root.c
|
||||
index 6a8ac1d..46a15d8 100644
|
||||
--- a/fs/proc/root.c
|
||||
+++ b/fs/proc/root.c
|
||||
@@ -38,10 +38,12 @@ static int proc_set_super(struct super_block *sb, void *data)
|
||||
}
|
||||
|
||||
enum {
|
||||
- Opt_err,
|
||||
+ Opt_gid, Opt_hidepid, Opt_err,
|
||||
};
|
||||
|
||||
static const match_table_t tokens = {
|
||||
+ {Opt_hidepid, "hidepid=%u"},
|
||||
+ {Opt_gid, "gid=%u"},
|
||||
{Opt_err, NULL},
|
||||
};
|
||||
|
||||
@@ -49,8 +51,7 @@ static int proc_parse_options(char *options, struct pid_namespace *pid)
|
||||
{
|
||||
char *p;
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
-
|
||||
- pr_debug("proc: options = %s\n", options);
|
||||
+ int option;
|
||||
|
||||
if (!options)
|
||||
return 1;
|
||||
@@ -63,6 +64,20 @@ static int proc_parse_options(char *options, struct pid_namespace *pid)
|
||||
args[0].to = args[0].from = 0;
|
||||
token = match_token(p, tokens, args);
|
||||
switch (token) {
|
||||
+ case Opt_gid:
|
||||
+ if (match_int(&args[0], &option))
|
||||
+ return 0;
|
||||
+ pid->pid_gid = option;
|
||||
+ break;
|
||||
+ case Opt_hidepid:
|
||||
+ if (match_int(&args[0], &option))
|
||||
+ return 0;
|
||||
+ if (option < 0 || option > 2) {
|
||||
+ pr_err("proc: hidepid value must be between 0 and 2.\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ pid->hide_pid = option;
|
||||
+ break;
|
||||
default:
|
||||
pr_err("proc: unrecognized mount option \"%s\" "
|
||||
"or missing value\n", p);
|
||||
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
|
||||
index 38d1032..e7cf666 100644
|
||||
--- a/include/linux/pid_namespace.h
|
||||
+++ b/include/linux/pid_namespace.h
|
||||
@@ -30,6 +30,8 @@ struct pid_namespace {
|
||||
#ifdef CONFIG_BSD_PROCESS_ACCT
|
||||
struct bsd_acct_struct *bacct;
|
||||
#endif
|
||||
+ gid_t pid_gid;
|
||||
+ int hide_pid;
|
||||
};
|
||||
|
||||
extern struct pid_namespace init_pid_ns;
|
||||
--
|
||||
1.7.7.5
|
||||
|
@ -1,173 +0,0 @@
|
||||
From 97412950b10e64f347aec4a9b759395c2465adf6 Mon Sep 17 00:00:00 2001
|
||||
From: Vasiliy Kulikov <segooon@gmail.com>
|
||||
Date: Tue, 10 Jan 2012 15:11:27 -0800
|
||||
Subject: [PATCH] procfs: parse mount options
|
||||
|
||||
Add support for procfs mount options. Actual mount options are coming in
|
||||
the next patches.
|
||||
|
||||
Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
|
||||
Cc: Alexey Dobriyan <adobriyan@gmail.com>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: Randy Dunlap <rdunlap@xenotime.net>
|
||||
Cc: "H. Peter Anvin" <hpa@zytor.com>
|
||||
Cc: Greg KH <greg@kroah.com>
|
||||
Cc: Theodore Tso <tytso@MIT.EDU>
|
||||
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
|
||||
Cc: James Morris <jmorris@namei.org>
|
||||
Cc: Oleg Nesterov <oleg@redhat.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
fs/proc/inode.c | 10 +++++++++
|
||||
fs/proc/internal.h | 1 +
|
||||
fs/proc/root.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 64 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
|
||||
index 51a1766..27c762f 100644
|
||||
--- a/fs/proc/inode.c
|
||||
+++ b/fs/proc/inode.c
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/time.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/kernel.h>
|
||||
+#include <linux/pid_namespace.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/stat.h>
|
||||
@@ -17,7 +18,9 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sysctl.h>
|
||||
+#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/mount.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
@@ -101,12 +104,19 @@ void __init proc_init_inodecache(void)
|
||||
init_once);
|
||||
}
|
||||
|
||||
+static int proc_show_options(struct seq_file *seq, struct vfsmount *vfs)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct super_operations proc_sops = {
|
||||
.alloc_inode = proc_alloc_inode,
|
||||
.destroy_inode = proc_destroy_inode,
|
||||
.drop_inode = generic_delete_inode,
|
||||
.evict_inode = proc_evict_inode,
|
||||
.statfs = simple_statfs,
|
||||
+ .remount_fs = proc_remount,
|
||||
+ .show_options = proc_show_options,
|
||||
};
|
||||
|
||||
static void __pde_users_dec(struct proc_dir_entry *pde)
|
||||
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
|
||||
index 7838e5c..2925775 100644
|
||||
--- a/fs/proc/internal.h
|
||||
+++ b/fs/proc/internal.h
|
||||
@@ -117,6 +117,7 @@ void pde_put(struct proc_dir_entry *pde);
|
||||
|
||||
int proc_fill_super(struct super_block *);
|
||||
struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *);
|
||||
+int proc_remount(struct super_block *sb, int *flags, char *data);
|
||||
|
||||
/*
|
||||
* These are generic /proc routines that use the internal
|
||||
diff --git a/fs/proc/root.c b/fs/proc/root.c
|
||||
index 03102d9..6a8ac1d 100644
|
||||
--- a/fs/proc/root.c
|
||||
+++ b/fs/proc/root.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/pid_namespace.h>
|
||||
+#include <linux/parser.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -36,6 +37,48 @@ static int proc_set_super(struct super_block *sb, void *data)
|
||||
return err;
|
||||
}
|
||||
|
||||
+enum {
|
||||
+ Opt_err,
|
||||
+};
|
||||
+
|
||||
+static const match_table_t tokens = {
|
||||
+ {Opt_err, NULL},
|
||||
+};
|
||||
+
|
||||
+static int proc_parse_options(char *options, struct pid_namespace *pid)
|
||||
+{
|
||||
+ char *p;
|
||||
+ substring_t args[MAX_OPT_ARGS];
|
||||
+
|
||||
+ pr_debug("proc: options = %s\n", options);
|
||||
+
|
||||
+ if (!options)
|
||||
+ return 1;
|
||||
+
|
||||
+ while ((p = strsep(&options, ",")) != NULL) {
|
||||
+ int token;
|
||||
+ if (!*p)
|
||||
+ continue;
|
||||
+
|
||||
+ args[0].to = args[0].from = 0;
|
||||
+ token = match_token(p, tokens, args);
|
||||
+ switch (token) {
|
||||
+ default:
|
||||
+ pr_err("proc: unrecognized mount option \"%s\" "
|
||||
+ "or missing value\n", p);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+int proc_remount(struct super_block *sb, int *flags, char *data)
|
||||
+{
|
||||
+ struct pid_namespace *pid = sb->s_fs_info;
|
||||
+ return !proc_parse_options(data, pid);
|
||||
+}
|
||||
+
|
||||
static struct dentry *proc_mount(struct file_system_type *fs_type,
|
||||
int flags, const char *dev_name, void *data)
|
||||
{
|
||||
@@ -43,11 +86,15 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
|
||||
struct super_block *sb;
|
||||
struct pid_namespace *ns;
|
||||
struct proc_inode *ei;
|
||||
+ char *options;
|
||||
|
||||
- if (flags & MS_KERNMOUNT)
|
||||
+ if (flags & MS_KERNMOUNT) {
|
||||
ns = (struct pid_namespace *)data;
|
||||
- else
|
||||
+ options = NULL;
|
||||
+ } else {
|
||||
ns = current->nsproxy->pid_ns;
|
||||
+ options = data;
|
||||
+ }
|
||||
|
||||
sb = sget(fs_type, proc_test_super, proc_set_super, ns);
|
||||
if (IS_ERR(sb))
|
||||
@@ -55,6 +102,10 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
|
||||
|
||||
if (!sb->s_root) {
|
||||
sb->s_flags = flags;
|
||||
+ if (!proc_parse_options(options, ns)) {
|
||||
+ deactivate_locked_super(sb);
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+ }
|
||||
err = proc_fill_super(sb);
|
||||
if (err) {
|
||||
deactivate_locked_super(sb);
|
||||
--
|
||||
1.7.7.5
|
||||
|
@ -1,8 +1,16 @@
|
||||
commit d80d983c0fbfe0b0f6bd83c4279e1077c31e7fe4
|
||||
Author: Josh Boyer <jwboyer@redhat.com>
|
||||
Date: Fri Jan 20 10:12:15 2012 -0500
|
||||
|
||||
Revert "x86: Serialize EFI time accesses on rtc_lock"
|
||||
|
||||
This reverts commit ef68c8f87ed13f65df867dddf36c0e185b27b942.
|
||||
|
||||
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
|
||||
index 3ae4128..e17c6d2 100644
|
||||
index 4cf9bd0..457e37a 100644
|
||||
--- a/arch/x86/platform/efi/efi.c
|
||||
+++ b/arch/x86/platform/efi/efi.c
|
||||
@@ -89,50 +89,26 @@ early_param("add_efi_memmap", setup_add_efi_memmap);
|
||||
@@ -90,50 +90,26 @@ early_param("add_efi_memmap", setup_add_efi_memmap);
|
||||
|
||||
static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
|
||||
{
|
||||
@ -59,7 +67,7 @@ index 3ae4128..e17c6d2 100644
|
||||
}
|
||||
|
||||
static efi_status_t virt_efi_get_variable(efi_char16_t *name,
|
||||
@@ -232,14 +208,11 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
|
||||
@@ -233,15 +209,12 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
|
||||
static efi_status_t __init phys_efi_get_time(efi_time_t *tm,
|
||||
efi_time_cap_t *tc)
|
||||
{
|
||||
@ -68,7 +76,8 @@ index 3ae4128..e17c6d2 100644
|
||||
|
||||
- spin_lock_irqsave(&rtc_lock, flags);
|
||||
efi_call_phys_prelog();
|
||||
status = efi_call_phys2(efi_phys.get_time, tm, tc);
|
||||
status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm),
|
||||
virt_to_phys(tc));
|
||||
efi_call_phys_epilog();
|
||||
- spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
return status;
|
||||
|
@ -1,163 +0,0 @@
|
||||
A recent LKML thread (http://lkml.indiana.edu/hypermail/linux/kernel/1112.3/00965.html)
|
||||
discusses warnings that occur during a suspend/resume cycle. The driver
|
||||
attempts to read the firmware file before userspace is ready, leading to the
|
||||
following warning:
|
||||
|
||||
WARNING: at drivers/base/firmware_class.c:537 _request_firmware+0x3f6/0x420()
|
||||
|
||||
For rtl8192cu, the problem is fixed by storing the firmware in a global buffer
|
||||
rather than one allocated per device. The usage count is increased when
|
||||
suspending and decreased when resuming. This way, the firmware is retained
|
||||
through a suspend/resume cycle, and does not have to be reread.
|
||||
|
||||
This patch should fix the bug reported in
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=771002.
|
||||
|
||||
Note: This patch also touches rtl8192ce as the "firmware" loaded message
|
||||
is now printed in the wrong place.
|
||||
Note: This patch also touches rtl8192ce as the "firmware" loaded message
|
||||
is now printed in the wrong place.
|
||||
|
||||
Reported-by: Mohammed Arafa <bugzilla@xxxxxxxxxxxx>
|
||||
Reported-by: Dave Jones <davej@xxxxxxxxxx>
|
||||
Signed-off-by: Larry Finger <Larry.Finger@xxxxxxxxxxxx>
|
||||
Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
|
||||
Cc: Stable <stable@xxxxxxxxxxxxxxx>
|
||||
|
||||
---
|
||||
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 1 -
|
||||
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 1 +
|
||||
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 58 +++++++++++++++++----
|
||||
3 files changed, 49 insertions(+), 11 deletions(-)
|
||||
|
||||
--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c 2012-01-13 13:07:58.830625006 -0500
|
||||
+++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c 2012-01-13 13:08:06.825439927 -0500
|
||||
@@ -227,7 +227,6 @@ int rtl92c_download_fw(struct ieee80211_
|
||||
u32 fwsize;
|
||||
enum version_8192c version = rtlhal->version;
|
||||
|
||||
- pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
|
||||
if (!rtlhal->pfirmware)
|
||||
return 1;
|
||||
|
||||
--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
|
||||
+++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
|
||||
@@ -186,6 +186,7 @@ int rtl92c_init_sw_vars(struct ieee80211
|
||||
memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
|
||||
rtlpriv->rtlhal.fwsize = firmware->size;
|
||||
release_firmware(firmware);
|
||||
+ pr_info("rtl8192ce: Loaded firmware file %s\n", rtlpriv->cfg->fw_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
|
||||
+++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
|
||||
@@ -43,6 +43,8 @@
|
||||
#include "hw.h"
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/atomic.h>
|
||||
+#include <linux/types.h>
|
||||
|
||||
MODULE_AUTHOR("Georgia <georgia@realtek.com>");
|
||||
MODULE_AUTHOR("Ziv Huang <ziv_huang@realtek.com>");
|
||||
@@ -51,6 +53,10 @@ MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");
|
||||
MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
|
||||
|
||||
+static char *rtl8192cu_firmware; /* pointer to firmware */
|
||||
+static int firmware_size;
|
||||
+static atomic_t usage_count;
|
||||
+
|
||||
static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
@@ -62,12 +68,21 @@ static int rtl92cu_init_sw_vars(struct i
|
||||
rtlpriv->dm.disable_framebursting = false;
|
||||
rtlpriv->dm.thermalvalue = 0;
|
||||
rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
|
||||
- rtlpriv->rtlhal.pfirmware = vmalloc(0x4000);
|
||||
- if (!rtlpriv->rtlhal.pfirmware) {
|
||||
+
|
||||
+ if (rtl8192cu_firmware) {
|
||||
+ /* firmware already loaded - true for suspend/resume
|
||||
+ * and multiple instances of the device */
|
||||
+ rtlpriv->rtlhal.pfirmware = rtl8192cu_firmware;
|
||||
+ rtlpriv->rtlhal.fwsize = firmware_size;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ rtl8192cu_firmware = vzalloc(0x4000);
|
||||
+ if (!rtl8192cu_firmware) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
("Can't alloc buffer for fw.\n"));
|
||||
return 1;
|
||||
}
|
||||
+
|
||||
/* request fw */
|
||||
err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
|
||||
rtlpriv->io.dev);
|
||||
@@ -82,9 +97,14 @@ static int rtl92cu_init_sw_vars(struct i
|
||||
release_firmware(firmware);
|
||||
return 1;
|
||||
}
|
||||
- memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
|
||||
+ pr_info("rtl8192cu: Loaded firmware from file %s\n",
|
||||
+ rtlpriv->cfg->fw_name);
|
||||
+ memcpy(rtl8192cu_firmware, firmware->data, firmware->size);
|
||||
+ firmware_size = firmware->size;
|
||||
rtlpriv->rtlhal.fwsize = firmware->size;
|
||||
+ rtlpriv->rtlhal.pfirmware = rtl8192cu_firmware;
|
||||
release_firmware(firmware);
|
||||
+ atomic_inc(&usage_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -93,12 +113,30 @@ static void rtl92cu_deinit_sw_vars(struc
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
- if (rtlpriv->rtlhal.pfirmware) {
|
||||
- vfree(rtlpriv->rtlhal.pfirmware);
|
||||
+ atomic_dec(&usage_count);
|
||||
+ if (!atomic_read(&usage_count) && rtlpriv->rtlhal.pfirmware) {
|
||||
+ vfree(rtl8192cu_firmware);
|
||||
+ rtl8192cu_firmware = NULL;
|
||||
rtlpriv->rtlhal.pfirmware = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+static int rtl8192cu_usb_suspend(struct usb_interface *pusb_intf,
|
||||
+ pm_message_t message)
|
||||
+{
|
||||
+ /* Increase usage_count to Save loaded fw across suspend/resume */
|
||||
+ atomic_inc(&usage_count);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int rtl8192cu_usb_resume(struct usb_interface *pusb_intf)
|
||||
+{
|
||||
+ atomic_dec(&usage_count); /* after resume, decrease usage count */
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static struct rtl_hal_ops rtl8192cu_hal_ops = {
|
||||
.init_sw_vars = rtl92cu_init_sw_vars,
|
||||
.deinit_sw_vars = rtl92cu_deinit_sw_vars,
|
||||
@@ -374,11 +412,10 @@ static struct usb_driver rtl8192cu_drive
|
||||
.disconnect = rtl_usb_disconnect,
|
||||
.id_table = rtl8192c_usb_ids,
|
||||
|
||||
-#ifdef CONFIG_PM
|
||||
- /* .suspend = rtl_usb_suspend, */
|
||||
- /* .resume = rtl_usb_resume, */
|
||||
- /* .reset_resume = rtl8192c_resume, */
|
||||
-#endif /* CONFIG_PM */
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+ .suspend = rtl8192cu_usb_suspend,
|
||||
+ .resume = rtl8192cu_usb_resume,
|
||||
+#endif /* CONFIG_PM_SLEEP */
|
||||
#ifdef CONFIG_AUTOSUSPEND
|
||||
.supports_autosuspend = 1,
|
||||
#endif
|
2
sources
2
sources
@ -1,3 +1,3 @@
|
||||
364066fa18767ec0ae5f4e4abcf9dc51 linux-3.2.tar.xz
|
||||
2fed18362598429cc0669c01123290ff compat-wireless-2012-01-09.tar.bz2
|
||||
62ac6ac9b870162f693ecf5e8606423a patch-3.2.1.xz
|
||||
1c3dd34fa219420a4cbed1e573d253e7 patch-3.3-rc1.xz
|
||||
|
@ -1,239 +0,0 @@
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Thu, 6 Oct 2011 18:08:18 +0000 (-0400)
|
||||
Subject: PCI/sysfs: add per pci device msi[x] irq listing (v5)
|
||||
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjbarnes%2Fpci.git;a=commitdiff_plain;h=933aa5c1f69aa650f59ba783307fc7ed7cc5fafa
|
||||
|
||||
PCI/sysfs: add per pci device msi[x] irq listing (v5)
|
||||
|
||||
This patch adds a per-pci-device subdirectory in sysfs called:
|
||||
/sys/bus/pci/devices/<device>/msi_irqs
|
||||
|
||||
This sub-directory exports the set of msi vectors allocated by a given
|
||||
pci device, by creating a numbered sub-directory for each vector beneath
|
||||
msi_irqs. For each vector various attributes can be exported.
|
||||
Currently the only attribute is called mode, which tracks the
|
||||
operational mode of that vector (msi vs. msix)
|
||||
|
||||
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
---
|
||||
|
||||
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
|
||||
index 349ecf2..34f5110 100644
|
||||
--- a/Documentation/ABI/testing/sysfs-bus-pci
|
||||
+++ b/Documentation/ABI/testing/sysfs-bus-pci
|
||||
@@ -66,6 +66,24 @@ Description:
|
||||
re-discover previously removed devices.
|
||||
Depends on CONFIG_HOTPLUG.
|
||||
|
||||
+What: /sys/bus/pci/devices/.../msi_irqs/
|
||||
+Date: September, 2011
|
||||
+Contact: Neil Horman <nhorman@tuxdriver.com>
|
||||
+Description:
|
||||
+ The /sys/devices/.../msi_irqs directory contains a variable set
|
||||
+ of sub-directories, with each sub-directory being named after a
|
||||
+ corresponding msi irq vector allocated to that device. Each
|
||||
+ numbered sub-directory N contains attributes of that irq.
|
||||
+ Note that this directory is not created for device drivers which
|
||||
+ do not support msi irqs
|
||||
+
|
||||
+What: /sys/bus/pci/devices/.../msi_irqs/<N>/mode
|
||||
+Date: September 2011
|
||||
+Contact: Neil Horman <nhorman@tuxdriver.com>
|
||||
+Description:
|
||||
+ This attribute indicates the mode that the irq vector named by
|
||||
+ the parent directory is in (msi vs. msix)
|
||||
+
|
||||
What: /sys/bus/pci/devices/.../remove
|
||||
Date: January 2009
|
||||
Contact: Linux PCI developers <linux-pci@vger.kernel.org>
|
||||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
|
||||
index 2f10328..73613e2 100644
|
||||
--- a/drivers/pci/msi.c
|
||||
+++ b/drivers/pci/msi.c
|
||||
@@ -322,6 +322,8 @@ static void free_msi_irqs(struct pci_dev *dev)
|
||||
if (list_is_last(&entry->list, &dev->msi_list))
|
||||
iounmap(entry->mask_base);
|
||||
}
|
||||
+ kobject_del(&entry->kobj);
|
||||
+ kobject_put(&entry->kobj);
|
||||
list_del(&entry->list);
|
||||
kfree(entry);
|
||||
}
|
||||
@@ -402,6 +404,98 @@ void pci_restore_msi_state(struct pci_dev *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_restore_msi_state);
|
||||
|
||||
+
|
||||
+#define to_msi_attr(obj) container_of(obj, struct msi_attribute, attr)
|
||||
+#define to_msi_desc(obj) container_of(obj, struct msi_desc, kobj)
|
||||
+
|
||||
+struct msi_attribute {
|
||||
+ struct attribute attr;
|
||||
+ ssize_t (*show)(struct msi_desc *entry, struct msi_attribute *attr,
|
||||
+ char *buf);
|
||||
+ ssize_t (*store)(struct msi_desc *entry, struct msi_attribute *attr,
|
||||
+ const char *buf, size_t count);
|
||||
+};
|
||||
+
|
||||
+static ssize_t show_msi_mode(struct msi_desc *entry, struct msi_attribute *atr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ return sprintf(buf, "%s\n", entry->msi_attrib.is_msix ? "msix" : "msi");
|
||||
+}
|
||||
+
|
||||
+static ssize_t msi_irq_attr_show(struct kobject *kobj,
|
||||
+ struct attribute *attr, char *buf)
|
||||
+{
|
||||
+ struct msi_attribute *attribute = to_msi_attr(attr);
|
||||
+ struct msi_desc *entry = to_msi_desc(kobj);
|
||||
+
|
||||
+ if (!attribute->show)
|
||||
+ return -EIO;
|
||||
+
|
||||
+ return attribute->show(entry, attribute, buf);
|
||||
+}
|
||||
+
|
||||
+static const struct sysfs_ops msi_irq_sysfs_ops = {
|
||||
+ .show = msi_irq_attr_show,
|
||||
+};
|
||||
+
|
||||
+static struct msi_attribute mode_attribute =
|
||||
+ __ATTR(mode, S_IRUGO, show_msi_mode, NULL);
|
||||
+
|
||||
+
|
||||
+struct attribute *msi_irq_default_attrs[] = {
|
||||
+ &mode_attribute.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+void msi_kobj_release(struct kobject *kobj)
|
||||
+{
|
||||
+ struct msi_desc *entry = to_msi_desc(kobj);
|
||||
+
|
||||
+ pci_dev_put(entry->dev);
|
||||
+}
|
||||
+
|
||||
+static struct kobj_type msi_irq_ktype = {
|
||||
+ .release = msi_kobj_release,
|
||||
+ .sysfs_ops = &msi_irq_sysfs_ops,
|
||||
+ .default_attrs = msi_irq_default_attrs,
|
||||
+};
|
||||
+
|
||||
+static int populate_msi_sysfs(struct pci_dev *pdev)
|
||||
+{
|
||||
+ struct msi_desc *entry;
|
||||
+ struct kobject *kobj;
|
||||
+ int ret;
|
||||
+ int count = 0;
|
||||
+
|
||||
+ pdev->msi_kset = kset_create_and_add("msi_irqs", NULL, &pdev->dev.kobj);
|
||||
+ if (!pdev->msi_kset)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ list_for_each_entry(entry, &pdev->msi_list, list) {
|
||||
+ kobj = &entry->kobj;
|
||||
+ kobj->kset = pdev->msi_kset;
|
||||
+ pci_dev_get(pdev);
|
||||
+ ret = kobject_init_and_add(kobj, &msi_irq_ktype, NULL,
|
||||
+ "%u", entry->irq);
|
||||
+ if (ret)
|
||||
+ goto out_unroll;
|
||||
+
|
||||
+ count++;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+out_unroll:
|
||||
+ list_for_each_entry(entry, &pdev->msi_list, list) {
|
||||
+ if (!count)
|
||||
+ break;
|
||||
+ kobject_del(&entry->kobj);
|
||||
+ kobject_put(&entry->kobj);
|
||||
+ count--;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* msi_capability_init - configure device's MSI capability structure
|
||||
* @dev: pointer to the pci_dev data structure of MSI device function
|
||||
@@ -453,6 +547,13 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = populate_msi_sysfs(dev);
|
||||
+ if (ret) {
|
||||
+ msi_mask_irq(entry, mask, ~mask);
|
||||
+ free_msi_irqs(dev);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
/* Set MSI enabled bits */
|
||||
pci_intx_for_msi(dev, 0);
|
||||
msi_set_enable(dev, pos, 1);
|
||||
@@ -573,6 +674,12 @@ static int msix_capability_init(struct pci_dev *dev,
|
||||
|
||||
msix_program_entries(dev, entries);
|
||||
|
||||
+ ret = populate_msi_sysfs(dev);
|
||||
+ if (ret) {
|
||||
+ ret = 0;
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
/* Set MSI-X enabled bits and unmask the function */
|
||||
pci_intx_for_msi(dev, 0);
|
||||
dev->msix_enabled = 1;
|
||||
@@ -731,6 +838,8 @@ void pci_disable_msi(struct pci_dev *dev)
|
||||
|
||||
pci_msi_shutdown(dev);
|
||||
free_msi_irqs(dev);
|
||||
+ kset_unregister(dev->msi_kset);
|
||||
+ dev->msi_kset = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_disable_msi);
|
||||
|
||||
@@ -829,6 +938,8 @@ void pci_disable_msix(struct pci_dev *dev)
|
||||
|
||||
pci_msix_shutdown(dev);
|
||||
free_msi_irqs(dev);
|
||||
+ kset_unregister(dev->msi_kset);
|
||||
+ dev->msi_kset = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_disable_msix);
|
||||
|
||||
diff --git a/include/linux/msi.h b/include/linux/msi.h
|
||||
index 05acced..ce93a34 100644
|
||||
--- a/include/linux/msi.h
|
||||
+++ b/include/linux/msi.h
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef LINUX_MSI_H
|
||||
#define LINUX_MSI_H
|
||||
|
||||
+#include <linux/kobject.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
struct msi_msg {
|
||||
@@ -44,6 +45,8 @@ struct msi_desc {
|
||||
|
||||
/* Last set MSI message */
|
||||
struct msi_msg msg;
|
||||
+
|
||||
+ struct kobject kobj;
|
||||
};
|
||||
|
||||
/*
|
||||
diff --git a/include/linux/pci.h b/include/linux/pci.h
|
||||
index 7cda65b..84225c7 100644
|
||||
--- a/include/linux/pci.h
|
||||
+++ b/include/linux/pci.h
|
||||
@@ -336,6 +336,7 @@ struct pci_dev {
|
||||
struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
struct list_head msi_list;
|
||||
+ struct kset *msi_kset;
|
||||
#endif
|
||||
struct pci_vpd *vpd;
|
||||
#ifdef CONFIG_PCI_ATS
|
Loading…
Reference in New Issue
Block a user