diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-29 17:36:33 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-29 17:36:33 -0500 |
| commit | a01af8e4a4ee1135598f157051959982418c38f8 (patch) | |
| tree | 76c78a7cbd02204afbe7404880dfbf312ebd51a5 | |
| parent | a9735c81a43054a7e8cb8771c8e04c01fcacde10 (diff) | |
| parent | 25888e30319f8896fc656fc68643e6a078263060 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (27 commits)
af_unix: limit recursion level
pch_gbe driver: The wrong of initializer entry
pch_gbe dreiver: chang author
ucc_geth: fix ucc halt problem in half duplex mode
inet: Fix __inet_inherit_port() to correctly increment bsockets and num_owners
ehea: Add some info messages and fix an issue
hso: fix disable_net
NET: wan/x25_asy, move lapb_unregister to x25_asy_close_tty
cxgb4vf: fix setting unicast/multicast addresses ...
net, ppp: Report correct error code if unit allocation failed
DECnet: don't leak uninitialized stack byte
au1000_eth: fix invalid address accessing the MAC enable register
dccp: fix error in updating the GAR
tcp: restrict net.ipv4.tcp_adv_win_scale (#20312)
netns: Don't leak others' openreq-s in proc
Net: ceph: Makefile: Remove unnessary code
vhost/net: fix rcu check usage
econet: fix CVE-2010-3848
econet: fix CVE-2010-3850
econet: disallow NULL remote addr for sendmsg(), fixes CVE-2010-3849
...
30 files changed, 280 insertions, 203 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index fe95105992c..3c5e465296e 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
| @@ -144,6 +144,7 @@ tcp_adv_win_scale - INTEGER | |||
| 144 | Count buffering overhead as bytes/2^tcp_adv_win_scale | 144 | Count buffering overhead as bytes/2^tcp_adv_win_scale |
| 145 | (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale), | 145 | (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale), |
| 146 | if it is <= 0. | 146 | if it is <= 0. |
| 147 | Possible values are [-31, 31], inclusive. | ||
| 147 | Default: 2 | 148 | Default: 2 |
| 148 | 149 | ||
| 149 | tcp_allowed_congestion_control - STRING | 150 | tcp_allowed_congestion_control - STRING |
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index 2e847a90bad..f2b5bab5e6a 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c | |||
| @@ -1627,7 +1627,7 @@ __setup("icn=", icn_setup); | |||
| 1627 | static int __init icn_init(void) | 1627 | static int __init icn_init(void) |
| 1628 | { | 1628 | { |
| 1629 | char *p; | 1629 | char *p; |
| 1630 | char rev[10]; | 1630 | char rev[20]; |
| 1631 | 1631 | ||
| 1632 | memset(&dev, 0, sizeof(icn_dev)); | 1632 | memset(&dev, 0, sizeof(icn_dev)); |
| 1633 | dev.memaddr = (membase & 0x0ffc000); | 1633 | dev.memaddr = (membase & 0x0ffc000); |
| @@ -1637,9 +1637,10 @@ static int __init icn_init(void) | |||
| 1637 | spin_lock_init(&dev.devlock); | 1637 | spin_lock_init(&dev.devlock); |
| 1638 | 1638 | ||
| 1639 | if ((p = strchr(revision, ':'))) { | 1639 | if ((p = strchr(revision, ':'))) { |
| 1640 | strcpy(rev, p + 1); | 1640 | strncpy(rev, p + 1, 20); |
| 1641 | p = strchr(rev, '$'); | 1641 | p = strchr(rev, '$'); |
| 1642 | *p = 0; | 1642 | if (p) |
| 1643 | *p = 0; | ||
| 1643 | } else | 1644 | } else |
| 1644 | strcpy(rev, " ??? "); | 1645 | strcpy(rev, " ??? "); |
| 1645 | printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev, | 1646 | printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev, |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 43db398437b..4f1755bddf6 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
| @@ -2543,10 +2543,10 @@ config PCH_GBE | |||
| 2543 | depends on PCI | 2543 | depends on PCI |
| 2544 | select MII | 2544 | select MII |
| 2545 | ---help--- | 2545 | ---help--- |
| 2546 | This is a gigabit ethernet driver for Topcliff PCH. | 2546 | This is a gigabit ethernet driver for EG20T PCH. |
| 2547 | Topcliff PCH is the platform controller hub that is used in Intel's | 2547 | EG20T PCH is the platform controller hub that is used in Intel's |
| 2548 | general embedded platform. | 2548 | general embedded platform. |
| 2549 | Topcliff PCH has Gigabit Ethernet interface. | 2549 | EG20T PCH has Gigabit Ethernet interface. |
| 2550 | Using this interface, it is able to access system devices connected | 2550 | Using this interface, it is able to access system devices connected |
| 2551 | to Gigabit Ethernet. | 2551 | to Gigabit Ethernet. |
| 2552 | This driver enables Gigabit Ethernet function. | 2552 | This driver enables Gigabit Ethernet function. |
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 43489f89c14..53eff9ba6e9 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
| @@ -155,10 +155,10 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset) | |||
| 155 | spin_lock_irqsave(&aup->lock, flags); | 155 | spin_lock_irqsave(&aup->lock, flags); |
| 156 | 156 | ||
| 157 | if (force_reset || (!aup->mac_enabled)) { | 157 | if (force_reset || (!aup->mac_enabled)) { |
| 158 | writel(MAC_EN_CLOCK_ENABLE, &aup->enable); | 158 | writel(MAC_EN_CLOCK_ENABLE, aup->enable); |
| 159 | au_sync_delay(2); | 159 | au_sync_delay(2); |
| 160 | writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | 160 | writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
| 161 | | MAC_EN_CLOCK_ENABLE), &aup->enable); | 161 | | MAC_EN_CLOCK_ENABLE), aup->enable); |
| 162 | au_sync_delay(2); | 162 | au_sync_delay(2); |
| 163 | 163 | ||
| 164 | aup->mac_enabled = 1; | 164 | aup->mac_enabled = 1; |
| @@ -503,9 +503,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev) | |||
| 503 | 503 | ||
| 504 | au1000_hard_stop(dev); | 504 | au1000_hard_stop(dev); |
| 505 | 505 | ||
| 506 | writel(MAC_EN_CLOCK_ENABLE, &aup->enable); | 506 | writel(MAC_EN_CLOCK_ENABLE, aup->enable); |
| 507 | au_sync_delay(2); | 507 | au_sync_delay(2); |
| 508 | writel(0, &aup->enable); | 508 | writel(0, aup->enable); |
| 509 | au_sync_delay(2); | 509 | au_sync_delay(2); |
| 510 | 510 | ||
| 511 | aup->tx_full = 0; | 511 | aup->tx_full = 0; |
| @@ -1119,7 +1119,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) | |||
| 1119 | /* set a random MAC now in case platform_data doesn't provide one */ | 1119 | /* set a random MAC now in case platform_data doesn't provide one */ |
| 1120 | random_ether_addr(dev->dev_addr); | 1120 | random_ether_addr(dev->dev_addr); |
| 1121 | 1121 | ||
| 1122 | writel(0, &aup->enable); | 1122 | writel(0, aup->enable); |
| 1123 | aup->mac_enabled = 0; | 1123 | aup->mac_enabled = 0; |
| 1124 | 1124 | ||
| 1125 | pd = pdev->dev.platform_data; | 1125 | pd = pdev->dev.platform_data; |
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index c3449bbc585..d887a76cd39 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
| @@ -816,40 +816,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev) | |||
| 816 | } | 816 | } |
| 817 | 817 | ||
| 818 | /* | 818 | /* |
| 819 | * Collect up to maxaddrs worth of a netdevice's unicast addresses into an | 819 | * Collect up to maxaddrs worth of a netdevice's unicast addresses, starting |
| 820 | * array of addrss pointers and return the number collected. | 820 | * at a specified offset within the list, into an array of addrss pointers and |
| 821 | * return the number collected. | ||
| 821 | */ | 822 | */ |
| 822 | static inline int collect_netdev_uc_list_addrs(const struct net_device *dev, | 823 | static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev, |
| 823 | const u8 **addr, | 824 | const u8 **addr, |
| 824 | unsigned int maxaddrs) | 825 | unsigned int offset, |
| 826 | unsigned int maxaddrs) | ||
| 825 | { | 827 | { |
| 828 | unsigned int index = 0; | ||
| 826 | unsigned int naddr = 0; | 829 | unsigned int naddr = 0; |
| 827 | const struct netdev_hw_addr *ha; | 830 | const struct netdev_hw_addr *ha; |
| 828 | 831 | ||
| 829 | for_each_dev_addr(dev, ha) { | 832 | for_each_dev_addr(dev, ha) |
| 830 | addr[naddr++] = ha->addr; | 833 | if (index++ >= offset) { |
| 831 | if (naddr >= maxaddrs) | 834 | addr[naddr++] = ha->addr; |
| 832 | break; | 835 | if (naddr >= maxaddrs) |
| 833 | } | 836 | break; |
| 837 | } | ||
| 834 | return naddr; | 838 | return naddr; |
| 835 | } | 839 | } |
| 836 | 840 | ||
| 837 | /* | 841 | /* |
| 838 | * Collect up to maxaddrs worth of a netdevice's multicast addresses into an | 842 | * Collect up to maxaddrs worth of a netdevice's multicast addresses, starting |
| 839 | * array of addrss pointers and return the number collected. | 843 | * at a specified offset within the list, into an array of addrss pointers and |
| 844 | * return the number collected. | ||
| 840 | */ | 845 | */ |
| 841 | static inline int collect_netdev_mc_list_addrs(const struct net_device *dev, | 846 | static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev, |
| 842 | const u8 **addr, | 847 | const u8 **addr, |
| 843 | unsigned int maxaddrs) | 848 | unsigned int offset, |
| 849 | unsigned int maxaddrs) | ||
| 844 | { | 850 | { |
| 851 | unsigned int index = 0; | ||
| 845 | unsigned int naddr = 0; | 852 | unsigned int naddr = 0; |
| 846 | const struct netdev_hw_addr *ha; | 853 | const struct netdev_hw_addr *ha; |
| 847 | 854 | ||
| 848 | netdev_for_each_mc_addr(ha, dev) { | 855 | netdev_for_each_mc_addr(ha, dev) |
| 849 | addr[naddr++] = ha->addr; | 856 | if (index++ >= offset) { |
| 850 | if (naddr >= maxaddrs) | 857 | addr[naddr++] = ha->addr; |
| 851 | break; | 858 | if (naddr >= maxaddrs) |
| 852 | } | 859 | break; |
| 860 | } | ||
| 853 | return naddr; | 861 | return naddr; |
| 854 | } | 862 | } |
| 855 | 863 | ||
| @@ -862,16 +870,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) | |||
| 862 | u64 mhash = 0; | 870 | u64 mhash = 0; |
| 863 | u64 uhash = 0; | 871 | u64 uhash = 0; |
| 864 | bool free = true; | 872 | bool free = true; |
| 865 | u16 filt_idx[7]; | 873 | unsigned int offset, naddr; |
| 866 | const u8 *addr[7]; | 874 | const u8 *addr[7]; |
| 867 | int ret, naddr = 0; | 875 | int ret; |
| 868 | const struct port_info *pi = netdev_priv(dev); | 876 | const struct port_info *pi = netdev_priv(dev); |
| 869 | 877 | ||
| 870 | /* first do the secondary unicast addresses */ | 878 | /* first do the secondary unicast addresses */ |
| 871 | naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr)); | 879 | for (offset = 0; ; offset += naddr) { |
| 872 | if (naddr > 0) { | 880 | naddr = collect_netdev_uc_list_addrs(dev, addr, offset, |
| 881 | ARRAY_SIZE(addr)); | ||
| 882 | if (naddr == 0) | ||
| 883 | break; | ||
| 884 | |||
| 873 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, | 885 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, |
| 874 | naddr, addr, filt_idx, &uhash, sleep); | 886 | naddr, addr, NULL, &uhash, sleep); |
| 875 | if (ret < 0) | 887 | if (ret < 0) |
| 876 | return ret; | 888 | return ret; |
| 877 | 889 | ||
| @@ -879,12 +891,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep) | |||
| 879 | } | 891 | } |
| 880 | 892 | ||
| 881 | /* next set up the multicast addresses */ | 893 | /* next set up the multicast addresses */ |
| 882 | naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr)); | 894 | for (offset = 0; ; offset += naddr) { |
| 883 | if (naddr > 0) { | 895 | naddr = collect_netdev_mc_list_addrs(dev, addr, offset, |
| 896 | ARRAY_SIZE(addr)); | ||
| 897 | if (naddr == 0) | ||
| 898 | break; | ||
| 899 | |||
| 884 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, | 900 | ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free, |
| 885 | naddr, addr, filt_idx, &mhash, sleep); | 901 | naddr, addr, NULL, &mhash, sleep); |
| 886 | if (ret < 0) | 902 | if (ret < 0) |
| 887 | return ret; | 903 | return ret; |
| 904 | free = false; | ||
| 888 | } | 905 | } |
| 889 | 906 | ||
| 890 | return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0, | 907 | return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0, |
diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c index e306c20dfae..19520afe1a1 100644 --- a/drivers/net/cxgb4vf/t4vf_hw.c +++ b/drivers/net/cxgb4vf/t4vf_hw.c | |||
| @@ -1014,48 +1014,72 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free, | |||
| 1014 | unsigned int naddr, const u8 **addr, u16 *idx, | 1014 | unsigned int naddr, const u8 **addr, u16 *idx, |
| 1015 | u64 *hash, bool sleep_ok) | 1015 | u64 *hash, bool sleep_ok) |
| 1016 | { | 1016 | { |
| 1017 | int i, ret; | 1017 | int offset, ret = 0; |
| 1018 | unsigned nfilters = 0; | ||
| 1019 | unsigned int rem = naddr; | ||
| 1018 | struct fw_vi_mac_cmd cmd, rpl; | 1020 | struct fw_vi_mac_cmd cmd, rpl; |
| 1019 | struct fw_vi_mac_exact *p; | ||
| 1020 | size_t len16; | ||
| 1021 | 1021 | ||
| 1022 | if (naddr > ARRAY_SIZE(cmd.u.exact)) | 1022 | if (naddr > FW_CLS_TCAM_NUM_ENTRIES) |
| 1023 | return -EINVAL; | 1023 | return -EINVAL; |
| 1024 | len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd, | ||
| 1025 | u.exact[naddr]), 16); | ||
| 1026 | 1024 | ||
| 1027 | memset(&cmd, 0, sizeof(cmd)); | 1025 | for (offset = 0; offset < naddr; /**/) { |
| 1028 | cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) | | 1026 | unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact) |
| 1029 | FW_CMD_REQUEST | | 1027 | ? rem |
| 1030 | FW_CMD_WRITE | | 1028 | : ARRAY_SIZE(cmd.u.exact)); |
| 1031 | (free ? FW_CMD_EXEC : 0) | | 1029 | size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd, |
| 1032 | FW_VI_MAC_CMD_VIID(viid)); | 1030 | u.exact[fw_naddr]), 16); |
| 1033 | cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) | | 1031 | struct fw_vi_mac_exact *p; |
| 1034 | FW_CMD_LEN16(len16)); | 1032 | int i; |
| 1035 | 1033 | ||
| 1036 | for (i = 0, p = cmd.u.exact; i < naddr; i++, p++) { | 1034 | memset(&cmd, 0, sizeof(cmd)); |
| 1037 | p->valid_to_idx = | 1035 | cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) | |
| 1038 | cpu_to_be16(FW_VI_MAC_CMD_VALID | | 1036 | FW_CMD_REQUEST | |
| 1039 | FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC)); | 1037 | FW_CMD_WRITE | |
| 1040 | memcpy(p->macaddr, addr[i], sizeof(p->macaddr)); | 1038 | (free ? FW_CMD_EXEC : 0) | |
| 1041 | } | 1039 | FW_VI_MAC_CMD_VIID(viid)); |
| 1040 | cmd.freemacs_to_len16 = | ||
| 1041 | cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) | | ||
| 1042 | FW_CMD_LEN16(len16)); | ||
| 1043 | |||
| 1044 | for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) { | ||
| 1045 | p->valid_to_idx = cpu_to_be16( | ||
| 1046 | FW_VI_MAC_CMD_VALID | | ||
| 1047 | FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC)); | ||
| 1048 | memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr)); | ||
| 1049 | } | ||
| 1050 | |||
| 1051 | |||
| 1052 | ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl, | ||
| 1053 | sleep_ok); | ||
| 1054 | if (ret && ret != -ENOMEM) | ||
| 1055 | break; | ||
| 1042 | 1056 | ||
| 1043 | ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl, sleep_ok); | 1057 | for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) { |
| 1044 | if (ret) | 1058 | u16 index = FW_VI_MAC_CMD_IDX_GET( |
| 1045 | return ret; | 1059 | be16_to_cpu(p->valid_to_idx)); |
| 1046 | 1060 | ||
| 1047 | for (i = 0, p = rpl.u.exact; i < naddr; i++, p++) { | 1061 | if (idx) |
| 1048 | u16 index = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx)); | 1062 | idx[offset+i] = |
| 1049 | 1063 | (index >= FW_CLS_TCAM_NUM_ENTRIES | |
| 1050 | if (idx) | 1064 | ? 0xffff |
| 1051 | idx[i] = (index >= FW_CLS_TCAM_NUM_ENTRIES | 1065 | : index); |
| 1052 | ? 0xffff | 1066 | if (index < FW_CLS_TCAM_NUM_ENTRIES) |
| 1053 | : index); | 1067 | nfilters++; |
| 1054 | if (index < FW_CLS_TCAM_NUM_ENTRIES) | 1068 | else if (hash) |
| 1055 | ret++; | 1069 | *hash |= (1ULL << hash_mac_addr(addr[offset+i])); |
| 1056 | else if (hash) | 1070 | } |
| 1057 | *hash |= (1 << hash_mac_addr(addr[i])); | 1071 | |
| 1072 | free = false; | ||
| 1073 | offset += fw_naddr; | ||
| 1074 | rem -= fw_naddr; | ||
| 1058 | } | 1075 | } |
| 1076 | |||
| 1077 | /* | ||
| 1078 | * If there were no errors or we merely ran out of room in our MAC | ||
| 1079 | * address arena, return the number of filters actually written. | ||
| 1080 | */ | ||
| 1081 | if (ret == 0 || ret == -ENOMEM) | ||
| 1082 | ret = nfilters; | ||
| 1059 | return ret; | 1083 | return ret; |
| 1060 | } | 1084 | } |
| 1061 | 1085 | ||
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 182b2a7be8d..3d0af08483a 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
| @@ -400,6 +400,7 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes) | |||
| 400 | skb_arr_rq1[index] = netdev_alloc_skb(dev, | 400 | skb_arr_rq1[index] = netdev_alloc_skb(dev, |
| 401 | EHEA_L_PKT_SIZE); | 401 | EHEA_L_PKT_SIZE); |
| 402 | if (!skb_arr_rq1[index]) { | 402 | if (!skb_arr_rq1[index]) { |
| 403 | ehea_info("Unable to allocate enough skb in the array\n"); | ||
| 403 | pr->rq1_skba.os_skbs = fill_wqes - i; | 404 | pr->rq1_skba.os_skbs = fill_wqes - i; |
| 404 | break; | 405 | break; |
| 405 | } | 406 | } |
| @@ -422,13 +423,20 @@ static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a) | |||
| 422 | struct net_device *dev = pr->port->netdev; | 423 | struct net_device *dev = pr->port->netdev; |
| 423 | int i; | 424 | int i; |
| 424 | 425 | ||
| 425 | for (i = 0; i < pr->rq1_skba.len; i++) { | 426 | if (nr_rq1a > pr->rq1_skba.len) { |
| 427 | ehea_error("NR_RQ1A bigger than skb array len\n"); | ||
| 428 | return; | ||
| 429 | } | ||
| 430 | |||
| 431 | for (i = 0; i < nr_rq1a; i++) { | ||
| 426 | skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); | 432 | skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); |
| 427 | if (!skb_arr_rq1[i]) | 433 | if (!skb_arr_rq1[i]) { |
| 434 | ehea_info("No enough memory to allocate skb array\n"); | ||
| 428 | break; | 435 | break; |
| 436 | } | ||
| 429 | } | 437 | } |
| 430 | /* Ring doorbell */ | 438 | /* Ring doorbell */ |
| 431 | ehea_update_rq1a(pr->qp, nr_rq1a); | 439 | ehea_update_rq1a(pr->qp, i); |
| 432 | } | 440 | } |
| 433 | 441 | ||
| 434 | static int ehea_refill_rq_def(struct ehea_port_res *pr, | 442 | static int ehea_refill_rq_def(struct ehea_port_res *pr, |
| @@ -735,8 +743,10 @@ static int ehea_proc_rwqes(struct net_device *dev, | |||
| 735 | 743 | ||
| 736 | skb = netdev_alloc_skb(dev, | 744 | skb = netdev_alloc_skb(dev, |
| 737 | EHEA_L_PKT_SIZE); | 745 | EHEA_L_PKT_SIZE); |
| 738 | if (!skb) | 746 | if (!skb) { |
| 747 | ehea_info("Not enough memory to allocate skb\n"); | ||
| 739 | break; | 748 | break; |
| 749 | } | ||
| 740 | } | 750 | } |
| 741 | skb_copy_to_linear_data(skb, ((char *)cqe) + 64, | 751 | skb_copy_to_linear_data(skb, ((char *)cqe) + 64, |
| 742 | cqe->num_bytes_transfered - 4); | 752 | cqe->num_bytes_transfered - 4); |
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 472056b4744..03a1d280105 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 1999 - 2010 Intel Corporation. | 2 | * Copyright (C) 1999 - 2010 Intel Corporation. |
| 3 | * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. | 3 | * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. |
| 4 | * | 4 | * |
| 5 | * This code was derived from the Intel e1000e Linux driver. | 5 | * This code was derived from the Intel e1000e Linux driver. |
| 6 | * | 6 | * |
| @@ -2464,8 +2464,8 @@ static void __exit pch_gbe_exit_module(void) | |||
| 2464 | module_init(pch_gbe_init_module); | 2464 | module_init(pch_gbe_init_module); |
| 2465 | module_exit(pch_gbe_exit_module); | 2465 | module_exit(pch_gbe_exit_module); |
| 2466 | 2466 | ||
| 2467 | MODULE_DESCRIPTION("OKI semiconductor PCH Gigabit ethernet Driver"); | 2467 | MODULE_DESCRIPTION("EG20T PCH Gigabit ethernet Driver"); |
| 2468 | MODULE_AUTHOR("OKI semiconductor, <masa-korg@dsn.okisemi.com>"); | 2468 | MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>"); |
| 2469 | MODULE_LICENSE("GPL"); | 2469 | MODULE_LICENSE("GPL"); |
| 2470 | MODULE_VERSION(DRV_VERSION); | 2470 | MODULE_VERSION(DRV_VERSION); |
| 2471 | MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id); | 2471 | MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id); |
diff --git a/drivers/net/pch_gbe/pch_gbe_param.c b/drivers/net/pch_gbe/pch_gbe_param.c index 2510146fc56..ef0996a0eaa 100644 --- a/drivers/net/pch_gbe/pch_gbe_param.c +++ b/drivers/net/pch_gbe/pch_gbe_param.c | |||
| @@ -434,8 +434,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter) | |||
| 434 | .err = "using default of " | 434 | .err = "using default of " |
| 435 | __MODULE_STRING(PCH_GBE_DEFAULT_TXD), | 435 | __MODULE_STRING(PCH_GBE_DEFAULT_TXD), |
| 436 | .def = PCH_GBE_DEFAULT_TXD, | 436 | .def = PCH_GBE_DEFAULT_TXD, |
| 437 | .arg = { .r = { .min = PCH_GBE_MIN_TXD } }, | 437 | .arg = { .r = { .min = PCH_GBE_MIN_TXD, |
| 438 | .arg = { .r = { .max = PCH_GBE_MAX_TXD } } | 438 | .max = PCH_GBE_MAX_TXD } } |
| 439 | }; | 439 | }; |
| 440 | struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; | 440 | struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; |
| 441 | tx_ring->count = TxDescriptors; | 441 | tx_ring->count = TxDescriptors; |
| @@ -450,8 +450,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter) | |||
| 450 | .err = "using default of " | 450 | .err = "using default of " |
| 451 | __MODULE_STRING(PCH_GBE_DEFAULT_RXD), | 451 | __MODULE_STRING(PCH_GBE_DEFAULT_RXD), |
| 452 | .def = PCH_GBE_DEFAULT_RXD, | 452 | .def = PCH_GBE_DEFAULT_RXD, |
| 453 | .arg = { .r = { .min = PCH_GBE_MIN_RXD } }, | 453 | .arg = { .r = { .min = PCH_GBE_MIN_RXD, |
| 454 | .arg = { .r = { .max = PCH_GBE_MAX_RXD } } | 454 | .max = PCH_GBE_MAX_RXD } } |
| 455 | }; | 455 | }; |
| 456 | struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; | 456 | struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; |
| 457 | rx_ring->count = RxDescriptors; | 457 | rx_ring->count = RxDescriptors; |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 09cf56d0416..39659976a1a 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
| @@ -2584,16 +2584,16 @@ ppp_create_interface(struct net *net, int unit, int *retp) | |||
| 2584 | */ | 2584 | */ |
| 2585 | dev_net_set(dev, net); | 2585 | dev_net_set(dev, net); |
| 2586 | 2586 | ||
| 2587 | ret = -EEXIST; | ||
| 2588 | mutex_lock(&pn->all_ppp_mutex); | 2587 | mutex_lock(&pn->all_ppp_mutex); |
| 2589 | 2588 | ||
| 2590 | if (unit < 0) { | 2589 | if (unit < 0) { |
| 2591 | unit = unit_get(&pn->units_idr, ppp); | 2590 | unit = unit_get(&pn->units_idr, ppp); |
| 2592 | if (unit < 0) { | 2591 | if (unit < 0) { |
| 2593 | *retp = unit; | 2592 | ret = unit; |
| 2594 | goto out2; | 2593 | goto out2; |
| 2595 | } | 2594 | } |
| 2596 | } else { | 2595 | } else { |
| 2596 | ret = -EEXIST; | ||
| 2597 | if (unit_find(&pn->units_idr, unit)) | 2597 | if (unit_find(&pn->units_idr, unit)) |
| 2598 | goto out2; /* unit already exists */ | 2598 | goto out2; /* unit already exists */ |
| 2599 | /* | 2599 | /* |
| @@ -2668,10 +2668,10 @@ static void ppp_shutdown_interface(struct ppp *ppp) | |||
| 2668 | ppp->closing = 1; | 2668 | ppp->closing = 1; |
| 2669 | ppp_unlock(ppp); | 2669 | ppp_unlock(ppp); |
| 2670 | unregister_netdev(ppp->dev); | 2670 | unregister_netdev(ppp->dev); |
| 2671 | unit_put(&pn->units_idr, ppp->file.index); | ||
| 2671 | } else | 2672 | } else |
| 2672 | ppp_unlock(ppp); | 2673 | ppp_unlock(ppp); |
| 2673 | 2674 | ||
| 2674 | unit_put(&pn->units_idr, ppp->file.index); | ||
| 2675 | ppp->file.dead = 1; | 2675 | ppp->file.dead = 1; |
| 2676 | ppp->owner = NULL; | 2676 | ppp->owner = NULL; |
| 2677 | wake_up_interruptible(&ppp->file.rwait); | 2677 | wake_up_interruptible(&ppp->file.rwait); |
| @@ -2859,8 +2859,7 @@ static void __exit ppp_cleanup(void) | |||
| 2859 | * by holding all_ppp_mutex | 2859 | * by holding all_ppp_mutex |
| 2860 | */ | 2860 | */ |
| 2861 | 2861 | ||
| 2862 | /* associate pointer with specified number */ | 2862 | static int __unit_alloc(struct idr *p, void *ptr, int n) |
| 2863 | static int unit_set(struct idr *p, void *ptr, int n) | ||
| 2864 | { | 2863 | { |
| 2865 | int unit, err; | 2864 | int unit, err; |
| 2866 | 2865 | ||
| @@ -2871,10 +2870,24 @@ again: | |||
| 2871 | } | 2870 | } |
| 2872 | 2871 | ||
| 2873 | err = idr_get_new_above(p, ptr, n, &unit); | 2872 | err = idr_get_new_above(p, ptr, n, &unit); |
| 2874 | if (err == -EAGAIN) | 2873 | if (err < 0) { |
| 2875 | goto again; | 2874 | if (err == -EAGAIN) |
| 2875 | goto again; | ||
| 2876 | return err; | ||
| 2877 | } | ||
| 2878 | |||
| 2879 | return unit; | ||
| 2880 | } | ||
| 2881 | |||
| 2882 | /* associate pointer with specified number */ | ||
| 2883 | static int unit_set(struct idr *p, void *ptr, int n) | ||
| 2884 | { | ||
| 2885 | int unit; | ||
| 2876 | 2886 | ||
| 2877 | if (unit != n) { | 2887 | unit = __unit_alloc(p, ptr, n); |
| 2888 | if (unit < 0) | ||
| 2889 | return unit; | ||
| 2890 | else if (unit != n) { | ||
| 2878 | idr_remove(p, unit); | 2891 | idr_remove(p, unit); |
| 2879 | return -EINVAL; | 2892 | return -EINVAL; |
| 2880 | } | 2893 | } |
| @@ -2885,19 +2898,7 @@ again: | |||
| 2885 | /* get new free unit number and associate pointer with it */ | 2898 | /* get new free unit number and associate pointer with it */ |
| 2886 | static int unit_get(struct idr *p, void *ptr) | 2899 | static int unit_get(struct idr *p, void *ptr) |
| 2887 | { | 2900 | { |
| 2888 | int unit, err; | 2901 | return __unit_alloc(p, ptr, 0); |
| 2889 | |||
| 2890 | again: | ||
| 2891 | if (!idr_pre_get(p, GFP_KERNEL)) { | ||
| 2892 | printk(KERN_ERR "PPP: No free memory for idr\n"); | ||
| 2893 | return -ENOMEM; | ||
| 2894 | } | ||
| 2895 | |||
| 2896 | err = idr_get_new_above(p, ptr, 0, &unit); | ||
| 2897 | if (err == -EAGAIN) | ||
| 2898 | goto again; | ||
| 2899 | |||
| 2900 | return unit; | ||
| 2901 | } | 2902 | } |
| 2902 | 2903 | ||
| 2903 | /* put unit number back to a pool */ | 2904 | /* put unit number back to a pool */ |
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 05a95586f3c..055b87ab4f0 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h | |||
| @@ -899,7 +899,8 @@ struct ucc_geth_hardware_statistics { | |||
| 899 | #define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size | 899 | #define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size |
| 900 | */ | 900 | */ |
| 901 | #define UCC_GETH_UTFET_INIT 256 /* 1/2 utfs */ | 901 | #define UCC_GETH_UTFET_INIT 256 /* 1/2 utfs */ |
| 902 | #define UCC_GETH_UTFTT_INIT 512 | 902 | #define UCC_GETH_UTFTT_INIT 256 /* 1/2 utfs |
| 903 | due to errata */ | ||
| 903 | /* Gigabit Ethernet (1000 Mbps) */ | 904 | /* Gigabit Ethernet (1000 Mbps) */ |
| 904 | #define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual | 905 | #define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual |
| 905 | FIFO size */ | 906 | FIFO size */ |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index b154a94de03..62e9e8dc819 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -2994,12 +2994,14 @@ static int hso_probe(struct usb_interface *interface, | |||
| 2994 | 2994 | ||
| 2995 | case HSO_INTF_BULK: | 2995 | case HSO_INTF_BULK: |
| 2996 | /* It's a regular bulk interface */ | 2996 | /* It's a regular bulk interface */ |
| 2997 | if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) && | 2997 | if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) { |
| 2998 | !disable_net) | 2998 | if (!disable_net) |
| 2999 | hso_dev = hso_create_net_device(interface, port_spec); | 2999 | hso_dev = |
| 3000 | else | 3000 | hso_create_net_device(interface, port_spec); |
| 3001 | } else { | ||
| 3001 | hso_dev = | 3002 | hso_dev = |
| 3002 | hso_create_bulk_serial_device(interface, port_spec); | 3003 | hso_create_bulk_serial_device(interface, port_spec); |
| 3004 | } | ||
| 3003 | if (!hso_dev) | 3005 | if (!hso_dev) |
| 3004 | goto exit; | 3006 | goto exit; |
| 3005 | break; | 3007 | break; |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index d81ad839788..cf05504d951 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
| @@ -498,7 +498,6 @@ norbuff: | |||
| 498 | static int x25_asy_close(struct net_device *dev) | 498 | static int x25_asy_close(struct net_device *dev) |
| 499 | { | 499 | { |
| 500 | struct x25_asy *sl = netdev_priv(dev); | 500 | struct x25_asy *sl = netdev_priv(dev); |
| 501 | int err; | ||
| 502 | 501 | ||
| 503 | spin_lock(&sl->lock); | 502 | spin_lock(&sl->lock); |
| 504 | if (sl->tty) | 503 | if (sl->tty) |
| @@ -507,10 +506,6 @@ static int x25_asy_close(struct net_device *dev) | |||
| 507 | netif_stop_queue(dev); | 506 | netif_stop_queue(dev); |
| 508 | sl->rcount = 0; | 507 | sl->rcount = 0; |
| 509 | sl->xleft = 0; | 508 | sl->xleft = 0; |
| 510 | err = lapb_unregister(dev); | ||
| 511 | if (err != LAPB_OK) | ||
| 512 | printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n", | ||
| 513 | err); | ||
| 514 | spin_unlock(&sl->lock); | 509 | spin_unlock(&sl->lock); |
| 515 | return 0; | 510 | return 0; |
| 516 | } | 511 | } |
| @@ -595,6 +590,7 @@ static int x25_asy_open_tty(struct tty_struct *tty) | |||
| 595 | static void x25_asy_close_tty(struct tty_struct *tty) | 590 | static void x25_asy_close_tty(struct tty_struct *tty) |
| 596 | { | 591 | { |
| 597 | struct x25_asy *sl = tty->disc_data; | 592 | struct x25_asy *sl = tty->disc_data; |
| 593 | int err; | ||
| 598 | 594 | ||
| 599 | /* First make sure we're connected. */ | 595 | /* First make sure we're connected. */ |
| 600 | if (!sl || sl->magic != X25_ASY_MAGIC) | 596 | if (!sl || sl->magic != X25_ASY_MAGIC) |
| @@ -605,6 +601,11 @@ static void x25_asy_close_tty(struct tty_struct *tty) | |||
| 605 | dev_close(sl->dev); | 601 | dev_close(sl->dev); |
| 606 | rtnl_unlock(); | 602 | rtnl_unlock(); |
| 607 | 603 | ||
| 604 | err = lapb_unregister(sl->dev); | ||
| 605 | if (err != LAPB_OK) | ||
| 606 | printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n", | ||
| 607 | err); | ||
| 608 | |||
| 608 | tty->disc_data = NULL; | 609 | tty->disc_data = NULL; |
| 609 | sl->tty = NULL; | 610 | sl->tty = NULL; |
| 610 | x25_asy_free(sl); | 611 | x25_asy_free(sl); |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c76ea53c20c..1a62e351ec7 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -518,7 +518,7 @@ bool ath_stoprecv(struct ath_softc *sc) | |||
| 518 | bool stopped; | 518 | bool stopped; |
| 519 | 519 | ||
| 520 | spin_lock_bh(&sc->rx.rxbuflock); | 520 | spin_lock_bh(&sc->rx.rxbuflock); |
| 521 | ath9k_hw_stoppcurecv(ah); | 521 | ath9k_hw_abortpcurecv(ah); |
| 522 | ath9k_hw_setrxfilter(ah, 0); | 522 | ath9k_hw_setrxfilter(ah, 0); |
| 523 | stopped = ath9k_hw_stopdmarecv(ah); | 523 | stopped = ath9k_hw_stopdmarecv(ah); |
| 524 | 524 | ||
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 980ae70ea42..a314c2c2bfb 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
| @@ -647,7 +647,7 @@ init: | |||
| 647 | } | 647 | } |
| 648 | 648 | ||
| 649 | unlock: | 649 | unlock: |
| 650 | if (err && (vif_id != -1)) { | 650 | if (err && (vif_id >= 0)) { |
| 651 | vif_priv->active = false; | 651 | vif_priv->active = false; |
| 652 | bitmap_release_region(&ar->vif_bitmap, vif_id, 0); | 652 | bitmap_release_region(&ar->vif_bitmap, vif_id, 0); |
| 653 | ar->vifs--; | 653 | ar->vifs--; |
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 9a55338d957..09e2dfd7b17 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c | |||
| @@ -163,6 +163,7 @@ static int b43_sdio_probe(struct sdio_func *func, | |||
| 163 | err_free_ssb: | 163 | err_free_ssb: |
| 164 | kfree(sdio); | 164 | kfree(sdio); |
| 165 | err_disable_func: | 165 | err_disable_func: |
| 166 | sdio_claim_host(func); | ||
| 166 | sdio_disable_func(func); | 167 | sdio_disable_func(func); |
| 167 | err_release_host: | 168 | err_release_host: |
| 168 | sdio_release_host(func); | 169 | sdio_release_host(func); |
diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c index ef9c6a04ad8..744d3f6e470 100644 --- a/drivers/ssb/b43_pci_bridge.c +++ b/drivers/ssb/b43_pci_bridge.c | |||
| @@ -24,6 +24,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { | |||
| 24 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) }, | 24 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) }, |
| 25 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) }, | 25 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) }, |
| 26 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) }, | 26 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) }, |
| 27 | { PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC, 0x4318) }, | ||
| 27 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) }, | 28 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) }, |
| 28 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) }, | 29 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) }, |
| 29 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, | 30 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 4b4da5b86ff..f442668a1e5 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
| @@ -129,8 +129,9 @@ static void handle_tx(struct vhost_net *net) | |||
| 129 | size_t hdr_size; | 129 | size_t hdr_size; |
| 130 | struct socket *sock; | 130 | struct socket *sock; |
| 131 | 131 | ||
| 132 | sock = rcu_dereference_check(vq->private_data, | 132 | /* TODO: check that we are running from vhost_worker? |
| 133 | lockdep_is_held(&vq->mutex)); | 133 | * Not sure it's worth it, it's straight-forward enough. */ |
| 134 | sock = rcu_dereference_check(vq->private_data, 1); | ||
| 134 | if (!sock) | 135 | if (!sock) |
| 135 | return; | 136 | return; |
| 136 | 137 | ||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index d369b533dc2..cb845c16ad7 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -2047,6 +2047,7 @@ | |||
| 2047 | #define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 | 2047 | #define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 |
| 2048 | #define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150 | 2048 | #define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150 |
| 2049 | 2049 | ||
| 2050 | #define PCI_VENDOR_ID_BCM_GVC 0x14a4 | ||
| 2050 | #define PCI_VENDOR_ID_BROADCOM 0x14e4 | 2051 | #define PCI_VENDOR_ID_BROADCOM 0x14e4 |
| 2051 | #define PCI_DEVICE_ID_TIGON3_5752 0x1600 | 2052 | #define PCI_DEVICE_ID_TIGON3_5752 0x1600 |
| 2052 | #define PCI_DEVICE_ID_TIGON3_5752M 0x1601 | 2053 | #define PCI_DEVICE_ID_TIGON3_5752M 0x1601 |
diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 90c9e2872f2..18e5c3f6758 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h | |||
| @@ -10,6 +10,7 @@ extern void unix_inflight(struct file *fp); | |||
| 10 | extern void unix_notinflight(struct file *fp); | 10 | extern void unix_notinflight(struct file *fp); |
| 11 | extern void unix_gc(void); | 11 | extern void unix_gc(void); |
| 12 | extern void wait_for_unix_gc(void); | 12 | extern void wait_for_unix_gc(void); |
| 13 | extern struct sock *unix_get_socket(struct file *filp); | ||
| 13 | 14 | ||
| 14 | #define UNIX_HASH_SIZE 256 | 15 | #define UNIX_HASH_SIZE 256 |
| 15 | 16 | ||
| @@ -56,6 +57,7 @@ struct unix_sock { | |||
| 56 | spinlock_t lock; | 57 | spinlock_t lock; |
| 57 | unsigned int gc_candidate : 1; | 58 | unsigned int gc_candidate : 1; |
| 58 | unsigned int gc_maybe_cycle : 1; | 59 | unsigned int gc_maybe_cycle : 1; |
| 60 | unsigned char recursion_level; | ||
| 59 | struct socket_wq peer_wq; | 61 | struct socket_wq peer_wq; |
| 60 | }; | 62 | }; |
| 61 | #define unix_sk(__sk) ((struct unix_sock *)__sk) | 63 | #define unix_sk(__sk) ((struct unix_sock *)__sk) |
diff --git a/net/ceph/Makefile b/net/ceph/Makefile index aab1cabb803..5f19415ec9c 100644 --- a/net/ceph/Makefile +++ b/net/ceph/Makefile | |||
| @@ -1,9 +1,6 @@ | |||
| 1 | # | 1 | # |
| 2 | # Makefile for CEPH filesystem. | 2 | # Makefile for CEPH filesystem. |
| 3 | # | 3 | # |
| 4 | |||
| 5 | ifneq ($(KERNELRELEASE),) | ||
| 6 | |||
| 7 | obj-$(CONFIG_CEPH_LIB) += libceph.o | 4 | obj-$(CONFIG_CEPH_LIB) += libceph.o |
| 8 | 5 | ||
| 9 | libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ | 6 | libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ |
| @@ -16,22 +13,3 @@ libceph-objs := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \ | |||
| 16 | ceph_fs.o ceph_strings.o ceph_hash.o \ | 13 | ceph_fs.o ceph_strings.o ceph_hash.o \ |
| 17 | pagevec.o | 14 | pagevec.o |
| 18 | 15 | ||
| 19 | else | ||
| 20 | #Otherwise we were called directly from the command | ||
| 21 | # line; invoke the kernel build system. | ||
| 22 | |||
| 23 | KERNELDIR ?= /lib/modules/$(shell uname -r)/build | ||
| 24 | PWD := $(shell pwd) | ||
| 25 | |||
| 26 | default: all | ||
| 27 | |||
| 28 | all: | ||
| 29 | $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules | ||
| 30 | |||
| 31 | modules_install: | ||
| 32 | $(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules_install | ||
| 33 | |||
| 34 | clean: | ||
| 35 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean | ||
| 36 | |||
| 37 | endif | ||
diff --git a/net/dccp/input.c b/net/dccp/input.c index 265985370fa..e424a09e83f 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
| @@ -239,7 +239,8 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) | |||
| 239 | dccp_update_gsr(sk, seqno); | 239 | dccp_update_gsr(sk, seqno); |
| 240 | 240 | ||
| 241 | if (dh->dccph_type != DCCP_PKT_SYNC && | 241 | if (dh->dccph_type != DCCP_PKT_SYNC && |
| 242 | (ackno != DCCP_PKT_WITHOUT_ACK_SEQ)) | 242 | ackno != DCCP_PKT_WITHOUT_ACK_SEQ && |
| 243 | after48(ackno, dp->dccps_gar)) | ||
| 243 | dp->dccps_gar = ackno; | 244 | dp->dccps_gar = ackno; |
| 244 | } else { | 245 | } else { |
| 245 | unsigned long now = jiffies; | 246 | unsigned long now = jiffies; |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index a76b78de679..6f97268ed85 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
| @@ -1556,6 +1556,8 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us | |||
| 1556 | if (r_len > sizeof(struct linkinfo_dn)) | 1556 | if (r_len > sizeof(struct linkinfo_dn)) |
| 1557 | r_len = sizeof(struct linkinfo_dn); | 1557 | r_len = sizeof(struct linkinfo_dn); |
| 1558 | 1558 | ||
| 1559 | memset(&link, 0, sizeof(link)); | ||
| 1560 | |||
| 1559 | switch(sock->state) { | 1561 | switch(sock->state) { |
| 1560 | case SS_CONNECTING: | 1562 | case SS_CONNECTING: |
| 1561 | link.idn_linkstate = LL_CONNECTING; | 1563 | link.idn_linkstate = LL_CONNECTING; |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index f8c1ae4b41f..13992e1d272 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
| 32 | #include <linux/udp.h> | 32 | #include <linux/udp.h> |
| 33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
| 34 | #include <linux/vmalloc.h> | ||
| 34 | #include <net/sock.h> | 35 | #include <net/sock.h> |
| 35 | #include <net/inet_common.h> | 36 | #include <net/inet_common.h> |
| 36 | #include <linux/stat.h> | 37 | #include <linux/stat.h> |
| @@ -276,12 +277,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 276 | #endif | 277 | #endif |
| 277 | #ifdef CONFIG_ECONET_AUNUDP | 278 | #ifdef CONFIG_ECONET_AUNUDP |
| 278 | struct msghdr udpmsg; | 279 | struct msghdr udpmsg; |
| 279 | struct iovec iov[msg->msg_iovlen+1]; | 280 | struct iovec iov[2]; |
| 280 | struct aunhdr ah; | 281 | struct aunhdr ah; |
| 281 | struct sockaddr_in udpdest; | 282 | struct sockaddr_in udpdest; |
| 282 | __kernel_size_t size; | 283 | __kernel_size_t size; |
| 283 | int i; | ||
| 284 | mm_segment_t oldfs; | 284 | mm_segment_t oldfs; |
| 285 | char *userbuf; | ||
| 285 | #endif | 286 | #endif |
| 286 | 287 | ||
| 287 | /* | 288 | /* |
| @@ -297,23 +298,14 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 297 | 298 | ||
| 298 | mutex_lock(&econet_mutex); | 299 | mutex_lock(&econet_mutex); |
| 299 | 300 | ||
| 300 | if (saddr == NULL) { | 301 | if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) { |
| 301 | struct econet_sock *eo = ec_sk(sk); | 302 | mutex_unlock(&econet_mutex); |
| 302 | 303 | return -EINVAL; | |
| 303 | addr.station = eo->station; | 304 | } |
| 304 | addr.net = eo->net; | 305 | addr.station = saddr->addr.station; |
| 305 | port = eo->port; | 306 | addr.net = saddr->addr.net; |
| 306 | cb = eo->cb; | 307 | port = saddr->port; |
| 307 | } else { | 308 | cb = saddr->cb; |
| 308 | if (msg->msg_namelen < sizeof(struct sockaddr_ec)) { | ||
| 309 | mutex_unlock(&econet_mutex); | ||
| 310 | return -EINVAL; | ||
| 311 | } | ||
| 312 | addr.station = saddr->addr.station; | ||
| 313 | addr.net = saddr->addr.net; | ||
| 314 | port = saddr->port; | ||
| 315 | cb = saddr->cb; | ||
| 316 | } | ||
| 317 | 309 | ||
| 318 | /* Look for a device with the right network number. */ | 310 | /* Look for a device with the right network number. */ |
| 319 | dev = net2dev_map[addr.net]; | 311 | dev = net2dev_map[addr.net]; |
| @@ -328,17 +320,17 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 328 | } | 320 | } |
| 329 | } | 321 | } |
| 330 | 322 | ||
| 331 | if (len + 15 > dev->mtu) { | ||
| 332 | mutex_unlock(&econet_mutex); | ||
| 333 | return -EMSGSIZE; | ||
| 334 | } | ||
| 335 | |||
| 336 | if (dev->type == ARPHRD_ECONET) { | 323 | if (dev->type == ARPHRD_ECONET) { |
| 337 | /* Real hardware Econet. We're not worthy etc. */ | 324 | /* Real hardware Econet. We're not worthy etc. */ |
| 338 | #ifdef CONFIG_ECONET_NATIVE | 325 | #ifdef CONFIG_ECONET_NATIVE |
| 339 | unsigned short proto = 0; | 326 | unsigned short proto = 0; |
| 340 | int res; | 327 | int res; |
| 341 | 328 | ||
| 329 | if (len + 15 > dev->mtu) { | ||
| 330 | mutex_unlock(&econet_mutex); | ||
| 331 | return -EMSGSIZE; | ||
| 332 | } | ||
| 333 | |||
| 342 | dev_hold(dev); | 334 | dev_hold(dev); |
| 343 | 335 | ||
| 344 | skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev), | 336 | skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev), |
| @@ -351,7 +343,6 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 351 | 343 | ||
| 352 | eb = (struct ec_cb *)&skb->cb; | 344 | eb = (struct ec_cb *)&skb->cb; |
| 353 | 345 | ||
| 354 | /* BUG: saddr may be NULL */ | ||
| 355 | eb->cookie = saddr->cookie; | 346 | eb->cookie = saddr->cookie; |
| 356 | eb->sec = *saddr; | 347 | eb->sec = *saddr; |
| 357 | eb->sent = ec_tx_done; | 348 | eb->sent = ec_tx_done; |
| @@ -415,6 +406,11 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 415 | return -ENETDOWN; /* No socket - can't send */ | 406 | return -ENETDOWN; /* No socket - can't send */ |
| 416 | } | 407 | } |
| 417 | 408 | ||
| 409 | if (len > 32768) { | ||
| 410 | err = -E2BIG; | ||
| 411 | goto error; | ||
| 412 | } | ||
| 413 | |||
| 418 | /* Make up a UDP datagram and hand it off to some higher intellect. */ | 414 | /* Make up a UDP datagram and hand it off to some higher intellect. */ |
| 419 | 415 | ||
| 420 | memset(&udpdest, 0, sizeof(udpdest)); | 416 | memset(&udpdest, 0, sizeof(udpdest)); |
| @@ -446,36 +442,26 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 446 | 442 | ||
| 447 | /* tack our header on the front of the iovec */ | 443 | /* tack our header on the front of the iovec */ |
| 448 | size = sizeof(struct aunhdr); | 444 | size = sizeof(struct aunhdr); |
| 449 | /* | ||
| 450 | * XXX: that is b0rken. We can't mix userland and kernel pointers | ||
| 451 | * in iovec, since on a lot of platforms copy_from_user() will | ||
| 452 | * *not* work with the kernel and userland ones at the same time, | ||
| 453 | * regardless of what we do with set_fs(). And we are talking about | ||
| 454 | * econet-over-ethernet here, so "it's only ARM anyway" doesn't | ||
| 455 | * apply. Any suggestions on fixing that code? -- AV | ||
| 456 | */ | ||
| 457 | iov[0].iov_base = (void *)&ah; | 445 | iov[0].iov_base = (void *)&ah; |
| 458 | iov[0].iov_len = size; | 446 | iov[0].iov_len = size; |
| 459 | for (i = 0; i < msg->msg_iovlen; i++) { | 447 | |
| 460 | void __user *base = msg->msg_iov[i].iov_base; | 448 | userbuf = vmalloc(len); |
| 461 | size_t iov_len = msg->msg_iov[i].iov_len; | 449 | if (userbuf == NULL) { |
| 462 | /* Check it now since we switch to KERNEL_DS later. */ | 450 | err = -ENOMEM; |
| 463 | if (!access_ok(VERIFY_READ, base, iov_len)) { | 451 | goto error; |
| 464 | mutex_unlock(&econet_mutex); | ||
| 465 | return -EFAULT; | ||
| 466 | } | ||
| 467 | iov[i+1].iov_base = base; | ||
| 468 | iov[i+1].iov_len = iov_len; | ||
| 469 | size += iov_len; | ||
| 470 | } | 452 | } |
| 471 | 453 | ||
| 454 | iov[1].iov_base = userbuf; | ||
| 455 | iov[1].iov_len = len; | ||
| 456 | err = memcpy_fromiovec(userbuf, msg->msg_iov, len); | ||
| 457 | if (err) | ||
| 458 | goto error_free_buf; | ||
| 459 | |||
| 472 | /* Get a skbuff (no data, just holds our cb information) */ | 460 | /* Get a skbuff (no data, just holds our cb information) */ |
| 473 | if ((skb = sock_alloc_send_skb(sk, 0, | 461 | if ((skb = sock_alloc_send_skb(sk, 0, |
| 474 | msg->msg_flags & MSG_DONTWAIT, | 462 | msg->msg_flags & MSG_DONTWAIT, |
| 475 | &err)) == NULL) { | 463 | &err)) == NULL) |
| 476 | mutex_unlock(&econet_mutex); | 464 | goto error_free_buf; |
| 477 | return err; | ||
| 478 | } | ||
| 479 | 465 | ||
| 480 | eb = (struct ec_cb *)&skb->cb; | 466 | eb = (struct ec_cb *)&skb->cb; |
| 481 | 467 | ||
| @@ -491,7 +477,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 491 | udpmsg.msg_name = (void *)&udpdest; | 477 | udpmsg.msg_name = (void *)&udpdest; |
| 492 | udpmsg.msg_namelen = sizeof(udpdest); | 478 | udpmsg.msg_namelen = sizeof(udpdest); |
| 493 | udpmsg.msg_iov = &iov[0]; | 479 | udpmsg.msg_iov = &iov[0]; |
| 494 | udpmsg.msg_iovlen = msg->msg_iovlen + 1; | 480 | udpmsg.msg_iovlen = 2; |
| 495 | udpmsg.msg_control = NULL; | 481 | udpmsg.msg_control = NULL; |
| 496 | udpmsg.msg_controllen = 0; | 482 | udpmsg.msg_controllen = 0; |
| 497 | udpmsg.msg_flags=0; | 483 | udpmsg.msg_flags=0; |
| @@ -499,9 +485,13 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 499 | oldfs = get_fs(); set_fs(KERNEL_DS); /* More privs :-) */ | 485 | oldfs = get_fs(); set_fs(KERNEL_DS); /* More privs :-) */ |
| 500 | err = sock_sendmsg(udpsock, &udpmsg, size); | 486 | err = sock_sendmsg(udpsock, &udpmsg, size); |
| 501 | set_fs(oldfs); | 487 | set_fs(oldfs); |
| 488 | |||
| 489 | error_free_buf: | ||
| 490 | vfree(userbuf); | ||
| 502 | #else | 491 | #else |
| 503 | err = -EPROTOTYPE; | 492 | err = -EPROTOTYPE; |
| 504 | #endif | 493 | #endif |
| 494 | error: | ||
| 505 | mutex_unlock(&econet_mutex); | 495 | mutex_unlock(&econet_mutex); |
| 506 | 496 | ||
| 507 | return err; | 497 | return err; |
| @@ -671,6 +661,9 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) | |||
| 671 | err = 0; | 661 | err = 0; |
| 672 | switch (cmd) { | 662 | switch (cmd) { |
| 673 | case SIOCSIFADDR: | 663 | case SIOCSIFADDR: |
| 664 | if (!capable(CAP_NET_ADMIN)) | ||
| 665 | return -EPERM; | ||
| 666 | |||
| 674 | edev = dev->ec_ptr; | 667 | edev = dev->ec_ptr; |
| 675 | if (edev == NULL) { | 668 | if (edev == NULL) { |
| 676 | /* Magic up a new one. */ | 669 | /* Magic up a new one. */ |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 1b344f30b46..3c0369a3a66 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
| @@ -133,8 +133,7 @@ int __inet_inherit_port(struct sock *sk, struct sock *child) | |||
| 133 | } | 133 | } |
| 134 | } | 134 | } |
| 135 | } | 135 | } |
| 136 | sk_add_bind_node(child, &tb->owners); | 136 | inet_bind_hash(child, tb, port); |
| 137 | inet_csk(child)->icsk_bind_hash = tb; | ||
| 138 | spin_unlock(&head->lock); | 137 | spin_unlock(&head->lock); |
| 139 | 138 | ||
| 140 | return 0; | 139 | return 0; |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index e91911d7aae..1b4ec21497a 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
| @@ -26,6 +26,8 @@ static int zero; | |||
| 26 | static int tcp_retr1_max = 255; | 26 | static int tcp_retr1_max = 255; |
| 27 | static int ip_local_port_range_min[] = { 1, 1 }; | 27 | static int ip_local_port_range_min[] = { 1, 1 }; |
| 28 | static int ip_local_port_range_max[] = { 65535, 65535 }; | 28 | static int ip_local_port_range_max[] = { 65535, 65535 }; |
| 29 | static int tcp_adv_win_scale_min = -31; | ||
| 30 | static int tcp_adv_win_scale_max = 31; | ||
| 29 | 31 | ||
| 30 | /* Update system visible IP port range */ | 32 | /* Update system visible IP port range */ |
| 31 | static void set_local_port_range(int range[2]) | 33 | static void set_local_port_range(int range[2]) |
| @@ -426,7 +428,9 @@ static struct ctl_table ipv4_table[] = { | |||
| 426 | .data = &sysctl_tcp_adv_win_scale, | 428 | .data = &sysctl_tcp_adv_win_scale, |
| 427 | .maxlen = sizeof(int), | 429 | .maxlen = sizeof(int), |
| 428 | .mode = 0644, | 430 | .mode = 0644, |
| 429 | .proc_handler = proc_dointvec | 431 | .proc_handler = proc_dointvec_minmax, |
| 432 | .extra1 = &tcp_adv_win_scale_min, | ||
| 433 | .extra2 = &tcp_adv_win_scale_max, | ||
| 430 | }, | 434 | }, |
| 431 | { | 435 | { |
| 432 | .procname = "tcp_tw_reuse", | 436 | .procname = "tcp_tw_reuse", |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 08141996948..f15c36a706e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -2246,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
| 2246 | /* Values greater than interface MTU won't take effect. However | 2246 | /* Values greater than interface MTU won't take effect. However |
| 2247 | * at the point when this call is done we typically don't yet | 2247 | * at the point when this call is done we typically don't yet |
| 2248 | * know which interface is going to be used */ | 2248 | * know which interface is going to be used */ |
| 2249 | if (val < 64 || val > MAX_TCP_WINDOW) { | 2249 | if (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW) { |
| 2250 | err = -EINVAL; | 2250 | err = -EINVAL; |
| 2251 | break; | 2251 | break; |
| 2252 | } | 2252 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 69ccbc1dde9..e13da6de1fc 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -2043,7 +2043,9 @@ get_req: | |||
| 2043 | } | 2043 | } |
| 2044 | get_sk: | 2044 | get_sk: |
| 2045 | sk_nulls_for_each_from(sk, node) { | 2045 | sk_nulls_for_each_from(sk, node) { |
| 2046 | if (sk->sk_family == st->family && net_eq(sock_net(sk), net)) { | 2046 | if (!net_eq(sock_net(sk), net)) |
| 2047 | continue; | ||
| 2048 | if (sk->sk_family == st->family) { | ||
| 2047 | cur = sk; | 2049 | cur = sk; |
| 2048 | goto out; | 2050 | goto out; |
| 2049 | } | 2051 | } |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 3c95304a081..2268e679812 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -1343,9 +1343,25 @@ static void unix_destruct_scm(struct sk_buff *skb) | |||
| 1343 | sock_wfree(skb); | 1343 | sock_wfree(skb); |
| 1344 | } | 1344 | } |
| 1345 | 1345 | ||
| 1346 | #define MAX_RECURSION_LEVEL 4 | ||
| 1347 | |||
| 1346 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | 1348 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) |
| 1347 | { | 1349 | { |
| 1348 | int i; | 1350 | int i; |
| 1351 | unsigned char max_level = 0; | ||
| 1352 | int unix_sock_count = 0; | ||
| 1353 | |||
| 1354 | for (i = scm->fp->count - 1; i >= 0; i--) { | ||
| 1355 | struct sock *sk = unix_get_socket(scm->fp->fp[i]); | ||
| 1356 | |||
| 1357 | if (sk) { | ||
| 1358 | unix_sock_count++; | ||
| 1359 | max_level = max(max_level, | ||
| 1360 | unix_sk(sk)->recursion_level); | ||
| 1361 | } | ||
| 1362 | } | ||
| 1363 | if (unlikely(max_level > MAX_RECURSION_LEVEL)) | ||
| 1364 | return -ETOOMANYREFS; | ||
| 1349 | 1365 | ||
| 1350 | /* | 1366 | /* |
| 1351 | * Need to duplicate file references for the sake of garbage | 1367 | * Need to duplicate file references for the sake of garbage |
| @@ -1356,9 +1372,11 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | |||
| 1356 | if (!UNIXCB(skb).fp) | 1372 | if (!UNIXCB(skb).fp) |
| 1357 | return -ENOMEM; | 1373 | return -ENOMEM; |
| 1358 | 1374 | ||
| 1359 | for (i = scm->fp->count-1; i >= 0; i--) | 1375 | if (unix_sock_count) { |
| 1360 | unix_inflight(scm->fp->fp[i]); | 1376 | for (i = scm->fp->count - 1; i >= 0; i--) |
| 1361 | return 0; | 1377 | unix_inflight(scm->fp->fp[i]); |
| 1378 | } | ||
| 1379 | return max_level; | ||
| 1362 | } | 1380 | } |
| 1363 | 1381 | ||
| 1364 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) | 1382 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) |
| @@ -1393,6 +1411,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1393 | struct sk_buff *skb; | 1411 | struct sk_buff *skb; |
| 1394 | long timeo; | 1412 | long timeo; |
| 1395 | struct scm_cookie tmp_scm; | 1413 | struct scm_cookie tmp_scm; |
| 1414 | int max_level; | ||
| 1396 | 1415 | ||
| 1397 | if (NULL == siocb->scm) | 1416 | if (NULL == siocb->scm) |
| 1398 | siocb->scm = &tmp_scm; | 1417 | siocb->scm = &tmp_scm; |
| @@ -1431,8 +1450,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1431 | goto out; | 1450 | goto out; |
| 1432 | 1451 | ||
| 1433 | err = unix_scm_to_skb(siocb->scm, skb, true); | 1452 | err = unix_scm_to_skb(siocb->scm, skb, true); |
| 1434 | if (err) | 1453 | if (err < 0) |
| 1435 | goto out_free; | 1454 | goto out_free; |
| 1455 | max_level = err + 1; | ||
| 1436 | unix_get_secdata(siocb->scm, skb); | 1456 | unix_get_secdata(siocb->scm, skb); |
| 1437 | 1457 | ||
| 1438 | skb_reset_transport_header(skb); | 1458 | skb_reset_transport_header(skb); |
| @@ -1514,6 +1534,8 @@ restart: | |||
| 1514 | if (sock_flag(other, SOCK_RCVTSTAMP)) | 1534 | if (sock_flag(other, SOCK_RCVTSTAMP)) |
| 1515 | __net_timestamp(skb); | 1535 | __net_timestamp(skb); |
| 1516 | skb_queue_tail(&other->sk_receive_queue, skb); | 1536 | skb_queue_tail(&other->sk_receive_queue, skb); |
| 1537 | if (max_level > unix_sk(other)->recursion_level) | ||
| 1538 | unix_sk(other)->recursion_level = max_level; | ||
| 1517 | unix_state_unlock(other); | 1539 | unix_state_unlock(other); |
| 1518 | other->sk_data_ready(other, len); | 1540 | other->sk_data_ready(other, len); |
| 1519 | sock_put(other); | 1541 | sock_put(other); |
| @@ -1544,6 +1566,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1544 | int sent = 0; | 1566 | int sent = 0; |
| 1545 | struct scm_cookie tmp_scm; | 1567 | struct scm_cookie tmp_scm; |
| 1546 | bool fds_sent = false; | 1568 | bool fds_sent = false; |
| 1569 | int max_level; | ||
| 1547 | 1570 | ||
| 1548 | if (NULL == siocb->scm) | 1571 | if (NULL == siocb->scm) |
| 1549 | siocb->scm = &tmp_scm; | 1572 | siocb->scm = &tmp_scm; |
| @@ -1607,10 +1630,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1607 | 1630 | ||
| 1608 | /* Only send the fds in the first buffer */ | 1631 | /* Only send the fds in the first buffer */ |
| 1609 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); | 1632 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); |
| 1610 | if (err) { | 1633 | if (err < 0) { |
| 1611 | kfree_skb(skb); | 1634 | kfree_skb(skb); |
| 1612 | goto out_err; | 1635 | goto out_err; |
| 1613 | } | 1636 | } |
| 1637 | max_level = err + 1; | ||
| 1614 | fds_sent = true; | 1638 | fds_sent = true; |
| 1615 | 1639 | ||
| 1616 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 1640 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
| @@ -1626,6 +1650,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1626 | goto pipe_err_free; | 1650 | goto pipe_err_free; |
| 1627 | 1651 | ||
| 1628 | skb_queue_tail(&other->sk_receive_queue, skb); | 1652 | skb_queue_tail(&other->sk_receive_queue, skb); |
| 1653 | if (max_level > unix_sk(other)->recursion_level) | ||
| 1654 | unix_sk(other)->recursion_level = max_level; | ||
| 1629 | unix_state_unlock(other); | 1655 | unix_state_unlock(other); |
| 1630 | other->sk_data_ready(other, size); | 1656 | other->sk_data_ready(other, size); |
| 1631 | sent += size; | 1657 | sent += size; |
| @@ -1845,6 +1871,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1845 | unix_state_lock(sk); | 1871 | unix_state_lock(sk); |
| 1846 | skb = skb_dequeue(&sk->sk_receive_queue); | 1872 | skb = skb_dequeue(&sk->sk_receive_queue); |
| 1847 | if (skb == NULL) { | 1873 | if (skb == NULL) { |
| 1874 | unix_sk(sk)->recursion_level = 0; | ||
| 1848 | if (copied >= target) | 1875 | if (copied >= target) |
| 1849 | goto unlock; | 1876 | goto unlock; |
| 1850 | 1877 | ||
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index c8df6fda0b1..f89f83bf828 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c | |||
| @@ -96,7 +96,7 @@ static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait); | |||
| 96 | unsigned int unix_tot_inflight; | 96 | unsigned int unix_tot_inflight; |
| 97 | 97 | ||
| 98 | 98 | ||
| 99 | static struct sock *unix_get_socket(struct file *filp) | 99 | struct sock *unix_get_socket(struct file *filp) |
| 100 | { | 100 | { |
| 101 | struct sock *u_sock = NULL; | 101 | struct sock *u_sock = NULL; |
| 102 | struct inode *inode = filp->f_path.dentry->d_inode; | 102 | struct inode *inode = filp->f_path.dentry->d_inode; |
| @@ -259,9 +259,16 @@ static void inc_inflight_move_tail(struct unix_sock *u) | |||
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | static bool gc_in_progress = false; | 261 | static bool gc_in_progress = false; |
| 262 | #define UNIX_INFLIGHT_TRIGGER_GC 16000 | ||
| 262 | 263 | ||
| 263 | void wait_for_unix_gc(void) | 264 | void wait_for_unix_gc(void) |
| 264 | { | 265 | { |
| 266 | /* | ||
| 267 | * If number of inflight sockets is insane, | ||
| 268 | * force a garbage collect right now. | ||
| 269 | */ | ||
| 270 | if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress) | ||
| 271 | unix_gc(); | ||
| 265 | wait_event(unix_gc_wait, gc_in_progress == false); | 272 | wait_event(unix_gc_wait, gc_in_progress == false); |
| 266 | } | 273 | } |
| 267 | 274 | ||
