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 ...
This commit is contained in:
commit
a01af8e4a4
@ -144,6 +144,7 @@ tcp_adv_win_scale - INTEGER
|
||||
Count buffering overhead as bytes/2^tcp_adv_win_scale
|
||||
(if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale),
|
||||
if it is <= 0.
|
||||
Possible values are [-31, 31], inclusive.
|
||||
Default: 2
|
||||
|
||||
tcp_allowed_congestion_control - STRING
|
||||
|
@ -1627,7 +1627,7 @@ __setup("icn=", icn_setup);
|
||||
static int __init icn_init(void)
|
||||
{
|
||||
char *p;
|
||||
char rev[10];
|
||||
char rev[20];
|
||||
|
||||
memset(&dev, 0, sizeof(icn_dev));
|
||||
dev.memaddr = (membase & 0x0ffc000);
|
||||
@ -1637,9 +1637,10 @@ static int __init icn_init(void)
|
||||
spin_lock_init(&dev.devlock);
|
||||
|
||||
if ((p = strchr(revision, ':'))) {
|
||||
strcpy(rev, p + 1);
|
||||
strncpy(rev, p + 1, 20);
|
||||
p = strchr(rev, '$');
|
||||
*p = 0;
|
||||
if (p)
|
||||
*p = 0;
|
||||
} else
|
||||
strcpy(rev, " ??? ");
|
||||
printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
|
||||
|
@ -2543,10 +2543,10 @@ config PCH_GBE
|
||||
depends on PCI
|
||||
select MII
|
||||
---help---
|
||||
This is a gigabit ethernet driver for Topcliff PCH.
|
||||
Topcliff PCH is the platform controller hub that is used in Intel's
|
||||
This is a gigabit ethernet driver for EG20T PCH.
|
||||
EG20T PCH is the platform controller hub that is used in Intel's
|
||||
general embedded platform.
|
||||
Topcliff PCH has Gigabit Ethernet interface.
|
||||
EG20T PCH has Gigabit Ethernet interface.
|
||||
Using this interface, it is able to access system devices connected
|
||||
to Gigabit Ethernet.
|
||||
This driver enables Gigabit Ethernet function.
|
||||
|
@ -155,10 +155,10 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset)
|
||||
spin_lock_irqsave(&aup->lock, flags);
|
||||
|
||||
if (force_reset || (!aup->mac_enabled)) {
|
||||
writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
|
||||
writel(MAC_EN_CLOCK_ENABLE, aup->enable);
|
||||
au_sync_delay(2);
|
||||
writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
|
||||
| MAC_EN_CLOCK_ENABLE), &aup->enable);
|
||||
| MAC_EN_CLOCK_ENABLE), aup->enable);
|
||||
au_sync_delay(2);
|
||||
|
||||
aup->mac_enabled = 1;
|
||||
@ -503,9 +503,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev)
|
||||
|
||||
au1000_hard_stop(dev);
|
||||
|
||||
writel(MAC_EN_CLOCK_ENABLE, &aup->enable);
|
||||
writel(MAC_EN_CLOCK_ENABLE, aup->enable);
|
||||
au_sync_delay(2);
|
||||
writel(0, &aup->enable);
|
||||
writel(0, aup->enable);
|
||||
au_sync_delay(2);
|
||||
|
||||
aup->tx_full = 0;
|
||||
@ -1119,7 +1119,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
|
||||
/* set a random MAC now in case platform_data doesn't provide one */
|
||||
random_ether_addr(dev->dev_addr);
|
||||
|
||||
writel(0, &aup->enable);
|
||||
writel(0, aup->enable);
|
||||
aup->mac_enabled = 0;
|
||||
|
||||
pd = pdev->dev.platform_data;
|
||||
|
@ -816,40 +816,48 @@ static struct net_device_stats *cxgb4vf_get_stats(struct net_device *dev)
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect up to maxaddrs worth of a netdevice's unicast addresses into an
|
||||
* array of addrss pointers and return the number collected.
|
||||
* Collect up to maxaddrs worth of a netdevice's unicast addresses, starting
|
||||
* at a specified offset within the list, into an array of addrss pointers and
|
||||
* return the number collected.
|
||||
*/
|
||||
static inline int collect_netdev_uc_list_addrs(const struct net_device *dev,
|
||||
const u8 **addr,
|
||||
unsigned int maxaddrs)
|
||||
static inline unsigned int collect_netdev_uc_list_addrs(const struct net_device *dev,
|
||||
const u8 **addr,
|
||||
unsigned int offset,
|
||||
unsigned int maxaddrs)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
unsigned int naddr = 0;
|
||||
const struct netdev_hw_addr *ha;
|
||||
|
||||
for_each_dev_addr(dev, ha) {
|
||||
addr[naddr++] = ha->addr;
|
||||
if (naddr >= maxaddrs)
|
||||
break;
|
||||
}
|
||||
for_each_dev_addr(dev, ha)
|
||||
if (index++ >= offset) {
|
||||
addr[naddr++] = ha->addr;
|
||||
if (naddr >= maxaddrs)
|
||||
break;
|
||||
}
|
||||
return naddr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Collect up to maxaddrs worth of a netdevice's multicast addresses into an
|
||||
* array of addrss pointers and return the number collected.
|
||||
* Collect up to maxaddrs worth of a netdevice's multicast addresses, starting
|
||||
* at a specified offset within the list, into an array of addrss pointers and
|
||||
* return the number collected.
|
||||
*/
|
||||
static inline int collect_netdev_mc_list_addrs(const struct net_device *dev,
|
||||
const u8 **addr,
|
||||
unsigned int maxaddrs)
|
||||
static inline unsigned int collect_netdev_mc_list_addrs(const struct net_device *dev,
|
||||
const u8 **addr,
|
||||
unsigned int offset,
|
||||
unsigned int maxaddrs)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
unsigned int naddr = 0;
|
||||
const struct netdev_hw_addr *ha;
|
||||
|
||||
netdev_for_each_mc_addr(ha, dev) {
|
||||
addr[naddr++] = ha->addr;
|
||||
if (naddr >= maxaddrs)
|
||||
break;
|
||||
}
|
||||
netdev_for_each_mc_addr(ha, dev)
|
||||
if (index++ >= offset) {
|
||||
addr[naddr++] = ha->addr;
|
||||
if (naddr >= maxaddrs)
|
||||
break;
|
||||
}
|
||||
return naddr;
|
||||
}
|
||||
|
||||
@ -862,16 +870,20 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
|
||||
u64 mhash = 0;
|
||||
u64 uhash = 0;
|
||||
bool free = true;
|
||||
u16 filt_idx[7];
|
||||
unsigned int offset, naddr;
|
||||
const u8 *addr[7];
|
||||
int ret, naddr = 0;
|
||||
int ret;
|
||||
const struct port_info *pi = netdev_priv(dev);
|
||||
|
||||
/* first do the secondary unicast addresses */
|
||||
naddr = collect_netdev_uc_list_addrs(dev, addr, ARRAY_SIZE(addr));
|
||||
if (naddr > 0) {
|
||||
for (offset = 0; ; offset += naddr) {
|
||||
naddr = collect_netdev_uc_list_addrs(dev, addr, offset,
|
||||
ARRAY_SIZE(addr));
|
||||
if (naddr == 0)
|
||||
break;
|
||||
|
||||
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
|
||||
naddr, addr, filt_idx, &uhash, sleep);
|
||||
naddr, addr, NULL, &uhash, sleep);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -879,12 +891,17 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
|
||||
}
|
||||
|
||||
/* next set up the multicast addresses */
|
||||
naddr = collect_netdev_mc_list_addrs(dev, addr, ARRAY_SIZE(addr));
|
||||
if (naddr > 0) {
|
||||
for (offset = 0; ; offset += naddr) {
|
||||
naddr = collect_netdev_mc_list_addrs(dev, addr, offset,
|
||||
ARRAY_SIZE(addr));
|
||||
if (naddr == 0)
|
||||
break;
|
||||
|
||||
ret = t4vf_alloc_mac_filt(pi->adapter, pi->viid, free,
|
||||
naddr, addr, filt_idx, &mhash, sleep);
|
||||
naddr, addr, NULL, &mhash, sleep);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
free = false;
|
||||
}
|
||||
|
||||
return t4vf_set_addr_hash(pi->adapter, pi->viid, uhash != 0,
|
||||
|
@ -1014,48 +1014,72 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
|
||||
unsigned int naddr, const u8 **addr, u16 *idx,
|
||||
u64 *hash, bool sleep_ok)
|
||||
{
|
||||
int i, ret;
|
||||
int offset, ret = 0;
|
||||
unsigned nfilters = 0;
|
||||
unsigned int rem = naddr;
|
||||
struct fw_vi_mac_cmd cmd, rpl;
|
||||
struct fw_vi_mac_exact *p;
|
||||
size_t len16;
|
||||
|
||||
if (naddr > ARRAY_SIZE(cmd.u.exact))
|
||||
if (naddr > FW_CLS_TCAM_NUM_ENTRIES)
|
||||
return -EINVAL;
|
||||
len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
|
||||
u.exact[naddr]), 16);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
|
||||
FW_CMD_REQUEST |
|
||||
FW_CMD_WRITE |
|
||||
(free ? FW_CMD_EXEC : 0) |
|
||||
FW_VI_MAC_CMD_VIID(viid));
|
||||
cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
|
||||
FW_CMD_LEN16(len16));
|
||||
for (offset = 0; offset < naddr; /**/) {
|
||||
unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact)
|
||||
? rem
|
||||
: ARRAY_SIZE(cmd.u.exact));
|
||||
size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
|
||||
u.exact[fw_naddr]), 16);
|
||||
struct fw_vi_mac_exact *p;
|
||||
int i;
|
||||
|
||||
for (i = 0, p = cmd.u.exact; i < naddr; i++, p++) {
|
||||
p->valid_to_idx =
|
||||
cpu_to_be16(FW_VI_MAC_CMD_VALID |
|
||||
FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
|
||||
memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
|
||||
FW_CMD_REQUEST |
|
||||
FW_CMD_WRITE |
|
||||
(free ? FW_CMD_EXEC : 0) |
|
||||
FW_VI_MAC_CMD_VIID(viid));
|
||||
cmd.freemacs_to_len16 =
|
||||
cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
|
||||
FW_CMD_LEN16(len16));
|
||||
|
||||
for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
|
||||
p->valid_to_idx = cpu_to_be16(
|
||||
FW_VI_MAC_CMD_VALID |
|
||||
FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
|
||||
memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
|
||||
}
|
||||
|
||||
|
||||
ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl,
|
||||
sleep_ok);
|
||||
if (ret && ret != -ENOMEM)
|
||||
break;
|
||||
|
||||
for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) {
|
||||
u16 index = FW_VI_MAC_CMD_IDX_GET(
|
||||
be16_to_cpu(p->valid_to_idx));
|
||||
|
||||
if (idx)
|
||||
idx[offset+i] =
|
||||
(index >= FW_CLS_TCAM_NUM_ENTRIES
|
||||
? 0xffff
|
||||
: index);
|
||||
if (index < FW_CLS_TCAM_NUM_ENTRIES)
|
||||
nfilters++;
|
||||
else if (hash)
|
||||
*hash |= (1ULL << hash_mac_addr(addr[offset+i]));
|
||||
}
|
||||
|
||||
free = false;
|
||||
offset += fw_naddr;
|
||||
rem -= fw_naddr;
|
||||
}
|
||||
|
||||
ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl, sleep_ok);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0, p = rpl.u.exact; i < naddr; i++, p++) {
|
||||
u16 index = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx));
|
||||
|
||||
if (idx)
|
||||
idx[i] = (index >= FW_CLS_TCAM_NUM_ENTRIES
|
||||
? 0xffff
|
||||
: index);
|
||||
if (index < FW_CLS_TCAM_NUM_ENTRIES)
|
||||
ret++;
|
||||
else if (hash)
|
||||
*hash |= (1 << hash_mac_addr(addr[i]));
|
||||
}
|
||||
/*
|
||||
* If there were no errors or we merely ran out of room in our MAC
|
||||
* address arena, return the number of filters actually written.
|
||||
*/
|
||||
if (ret == 0 || ret == -ENOMEM)
|
||||
ret = nfilters;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -400,6 +400,7 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
|
||||
skb_arr_rq1[index] = netdev_alloc_skb(dev,
|
||||
EHEA_L_PKT_SIZE);
|
||||
if (!skb_arr_rq1[index]) {
|
||||
ehea_info("Unable to allocate enough skb in the array\n");
|
||||
pr->rq1_skba.os_skbs = fill_wqes - i;
|
||||
break;
|
||||
}
|
||||
@ -422,13 +423,20 @@ static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
|
||||
struct net_device *dev = pr->port->netdev;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pr->rq1_skba.len; i++) {
|
||||
if (nr_rq1a > pr->rq1_skba.len) {
|
||||
ehea_error("NR_RQ1A bigger than skb array len\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < nr_rq1a; i++) {
|
||||
skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE);
|
||||
if (!skb_arr_rq1[i])
|
||||
if (!skb_arr_rq1[i]) {
|
||||
ehea_info("No enough memory to allocate skb array\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Ring doorbell */
|
||||
ehea_update_rq1a(pr->qp, nr_rq1a);
|
||||
ehea_update_rq1a(pr->qp, i);
|
||||
}
|
||||
|
||||
static int ehea_refill_rq_def(struct ehea_port_res *pr,
|
||||
@ -735,8 +743,10 @@ static int ehea_proc_rwqes(struct net_device *dev,
|
||||
|
||||
skb = netdev_alloc_skb(dev,
|
||||
EHEA_L_PKT_SIZE);
|
||||
if (!skb)
|
||||
if (!skb) {
|
||||
ehea_info("Not enough memory to allocate skb\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
skb_copy_to_linear_data(skb, ((char *)cqe) + 64,
|
||||
cqe->num_bytes_transfered - 4);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 1999 - 2010 Intel Corporation.
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
|
||||
*
|
||||
* This code was derived from the Intel e1000e Linux driver.
|
||||
*
|
||||
@ -2464,8 +2464,8 @@ static void __exit pch_gbe_exit_module(void)
|
||||
module_init(pch_gbe_init_module);
|
||||
module_exit(pch_gbe_exit_module);
|
||||
|
||||
MODULE_DESCRIPTION("OKI semiconductor PCH Gigabit ethernet Driver");
|
||||
MODULE_AUTHOR("OKI semiconductor, <masa-korg@dsn.okisemi.com>");
|
||||
MODULE_DESCRIPTION("EG20T PCH Gigabit ethernet Driver");
|
||||
MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id);
|
||||
|
@ -434,8 +434,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
|
||||
.err = "using default of "
|
||||
__MODULE_STRING(PCH_GBE_DEFAULT_TXD),
|
||||
.def = PCH_GBE_DEFAULT_TXD,
|
||||
.arg = { .r = { .min = PCH_GBE_MIN_TXD } },
|
||||
.arg = { .r = { .max = PCH_GBE_MAX_TXD } }
|
||||
.arg = { .r = { .min = PCH_GBE_MIN_TXD,
|
||||
.max = PCH_GBE_MAX_TXD } }
|
||||
};
|
||||
struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring;
|
||||
tx_ring->count = TxDescriptors;
|
||||
@ -450,8 +450,8 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
|
||||
.err = "using default of "
|
||||
__MODULE_STRING(PCH_GBE_DEFAULT_RXD),
|
||||
.def = PCH_GBE_DEFAULT_RXD,
|
||||
.arg = { .r = { .min = PCH_GBE_MIN_RXD } },
|
||||
.arg = { .r = { .max = PCH_GBE_MAX_RXD } }
|
||||
.arg = { .r = { .min = PCH_GBE_MIN_RXD,
|
||||
.max = PCH_GBE_MAX_RXD } }
|
||||
};
|
||||
struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring;
|
||||
rx_ring->count = RxDescriptors;
|
||||
|
@ -2584,16 +2584,16 @@ ppp_create_interface(struct net *net, int unit, int *retp)
|
||||
*/
|
||||
dev_net_set(dev, net);
|
||||
|
||||
ret = -EEXIST;
|
||||
mutex_lock(&pn->all_ppp_mutex);
|
||||
|
||||
if (unit < 0) {
|
||||
unit = unit_get(&pn->units_idr, ppp);
|
||||
if (unit < 0) {
|
||||
*retp = unit;
|
||||
ret = unit;
|
||||
goto out2;
|
||||
}
|
||||
} else {
|
||||
ret = -EEXIST;
|
||||
if (unit_find(&pn->units_idr, unit))
|
||||
goto out2; /* unit already exists */
|
||||
/*
|
||||
@ -2668,10 +2668,10 @@ static void ppp_shutdown_interface(struct ppp *ppp)
|
||||
ppp->closing = 1;
|
||||
ppp_unlock(ppp);
|
||||
unregister_netdev(ppp->dev);
|
||||
unit_put(&pn->units_idr, ppp->file.index);
|
||||
} else
|
||||
ppp_unlock(ppp);
|
||||
|
||||
unit_put(&pn->units_idr, ppp->file.index);
|
||||
ppp->file.dead = 1;
|
||||
ppp->owner = NULL;
|
||||
wake_up_interruptible(&ppp->file.rwait);
|
||||
@ -2859,8 +2859,7 @@ static void __exit ppp_cleanup(void)
|
||||
* by holding all_ppp_mutex
|
||||
*/
|
||||
|
||||
/* associate pointer with specified number */
|
||||
static int unit_set(struct idr *p, void *ptr, int n)
|
||||
static int __unit_alloc(struct idr *p, void *ptr, int n)
|
||||
{
|
||||
int unit, err;
|
||||
|
||||
@ -2871,10 +2870,24 @@ again:
|
||||
}
|
||||
|
||||
err = idr_get_new_above(p, ptr, n, &unit);
|
||||
if (err == -EAGAIN)
|
||||
goto again;
|
||||
if (err < 0) {
|
||||
if (err == -EAGAIN)
|
||||
goto again;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (unit != n) {
|
||||
return unit;
|
||||
}
|
||||
|
||||
/* associate pointer with specified number */
|
||||
static int unit_set(struct idr *p, void *ptr, int n)
|
||||
{
|
||||
int unit;
|
||||
|
||||
unit = __unit_alloc(p, ptr, n);
|
||||
if (unit < 0)
|
||||
return unit;
|
||||
else if (unit != n) {
|
||||
idr_remove(p, unit);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -2885,19 +2898,7 @@ again:
|
||||
/* get new free unit number and associate pointer with it */
|
||||
static int unit_get(struct idr *p, void *ptr)
|
||||
{
|
||||
int unit, err;
|
||||
|
||||
again:
|
||||
if (!idr_pre_get(p, GFP_KERNEL)) {
|
||||
printk(KERN_ERR "PPP: No free memory for idr\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
err = idr_get_new_above(p, ptr, 0, &unit);
|
||||
if (err == -EAGAIN)
|
||||
goto again;
|
||||
|
||||
return unit;
|
||||
return __unit_alloc(p, ptr, 0);
|
||||
}
|
||||
|
||||
/* put unit number back to a pool */
|
||||
|
@ -899,7 +899,8 @@ struct ucc_geth_hardware_statistics {
|
||||
#define UCC_GETH_UTFS_INIT 512 /* Tx virtual FIFO size
|
||||
*/
|
||||
#define UCC_GETH_UTFET_INIT 256 /* 1/2 utfs */
|
||||
#define UCC_GETH_UTFTT_INIT 512
|
||||
#define UCC_GETH_UTFTT_INIT 256 /* 1/2 utfs
|
||||
due to errata */
|
||||
/* Gigabit Ethernet (1000 Mbps) */
|
||||
#define UCC_GETH_URFS_GIGA_INIT 4096/*2048*/ /* Rx virtual
|
||||
FIFO size */
|
||||
|
@ -2994,12 +2994,14 @@ static int hso_probe(struct usb_interface *interface,
|
||||
|
||||
case HSO_INTF_BULK:
|
||||
/* It's a regular bulk interface */
|
||||
if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) &&
|
||||
!disable_net)
|
||||
hso_dev = hso_create_net_device(interface, port_spec);
|
||||
else
|
||||
if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
|
||||
if (!disable_net)
|
||||
hso_dev =
|
||||
hso_create_net_device(interface, port_spec);
|
||||
} else {
|
||||
hso_dev =
|
||||
hso_create_bulk_serial_device(interface, port_spec);
|
||||
}
|
||||
if (!hso_dev)
|
||||
goto exit;
|
||||
break;
|
||||
|
@ -498,7 +498,6 @@ norbuff:
|
||||
static int x25_asy_close(struct net_device *dev)
|
||||
{
|
||||
struct x25_asy *sl = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
spin_lock(&sl->lock);
|
||||
if (sl->tty)
|
||||
@ -507,10 +506,6 @@ static int x25_asy_close(struct net_device *dev)
|
||||
netif_stop_queue(dev);
|
||||
sl->rcount = 0;
|
||||
sl->xleft = 0;
|
||||
err = lapb_unregister(dev);
|
||||
if (err != LAPB_OK)
|
||||
printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
|
||||
err);
|
||||
spin_unlock(&sl->lock);
|
||||
return 0;
|
||||
}
|
||||
@ -595,6 +590,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
|
||||
static void x25_asy_close_tty(struct tty_struct *tty)
|
||||
{
|
||||
struct x25_asy *sl = tty->disc_data;
|
||||
int err;
|
||||
|
||||
/* First make sure we're connected. */
|
||||
if (!sl || sl->magic != X25_ASY_MAGIC)
|
||||
@ -605,6 +601,11 @@ static void x25_asy_close_tty(struct tty_struct *tty)
|
||||
dev_close(sl->dev);
|
||||
rtnl_unlock();
|
||||
|
||||
err = lapb_unregister(sl->dev);
|
||||
if (err != LAPB_OK)
|
||||
printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",
|
||||
err);
|
||||
|
||||
tty->disc_data = NULL;
|
||||
sl->tty = NULL;
|
||||
x25_asy_free(sl);
|
||||
|
@ -518,7 +518,7 @@ bool ath_stoprecv(struct ath_softc *sc)
|
||||
bool stopped;
|
||||
|
||||
spin_lock_bh(&sc->rx.rxbuflock);
|
||||
ath9k_hw_stoppcurecv(ah);
|
||||
ath9k_hw_abortpcurecv(ah);
|
||||
ath9k_hw_setrxfilter(ah, 0);
|
||||
stopped = ath9k_hw_stopdmarecv(ah);
|
||||
|
||||
|
@ -647,7 +647,7 @@ init:
|
||||
}
|
||||
|
||||
unlock:
|
||||
if (err && (vif_id != -1)) {
|
||||
if (err && (vif_id >= 0)) {
|
||||
vif_priv->active = false;
|
||||
bitmap_release_region(&ar->vif_bitmap, vif_id, 0);
|
||||
ar->vifs--;
|
||||
|
@ -163,6 +163,7 @@ static int b43_sdio_probe(struct sdio_func *func,
|
||||
err_free_ssb:
|
||||
kfree(sdio);
|
||||
err_disable_func:
|
||||
sdio_claim_host(func);
|
||||
sdio_disable_func(func);
|
||||
err_release_host:
|
||||
sdio_release_host(func);
|
||||
|
@ -24,6 +24,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC, 0x4318) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
|
||||
|
@ -129,8 +129,9 @@ static void handle_tx(struct vhost_net *net)
|
||||
size_t hdr_size;
|
||||
struct socket *sock;
|
||||
|
||||
sock = rcu_dereference_check(vq->private_data,
|
||||
lockdep_is_held(&vq->mutex));
|
||||
/* TODO: check that we are running from vhost_worker?
|
||||
* Not sure it's worth it, it's straight-forward enough. */
|
||||
sock = rcu_dereference_check(vq->private_data, 1);
|
||||
if (!sock)
|
||||
return;
|
||||
|
||||
|
@ -2047,6 +2047,7 @@
|
||||
#define PCI_DEVICE_ID_AFAVLAB_P030 0x2182
|
||||
#define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150
|
||||
|
||||
#define PCI_VENDOR_ID_BCM_GVC 0x14a4
|
||||
#define PCI_VENDOR_ID_BROADCOM 0x14e4
|
||||
#define PCI_DEVICE_ID_TIGON3_5752 0x1600
|
||||
#define PCI_DEVICE_ID_TIGON3_5752M 0x1601
|
||||
|
@ -10,6 +10,7 @@ extern void unix_inflight(struct file *fp);
|
||||
extern void unix_notinflight(struct file *fp);
|
||||
extern void unix_gc(void);
|
||||
extern void wait_for_unix_gc(void);
|
||||
extern struct sock *unix_get_socket(struct file *filp);
|
||||
|
||||
#define UNIX_HASH_SIZE 256
|
||||
|
||||
@ -56,6 +57,7 @@ struct unix_sock {
|
||||
spinlock_t lock;
|
||||
unsigned int gc_candidate : 1;
|
||||
unsigned int gc_maybe_cycle : 1;
|
||||
unsigned char recursion_level;
|
||||
struct socket_wq peer_wq;
|
||||
};
|
||||
#define unix_sk(__sk) ((struct unix_sock *)__sk)
|
||||
|
@ -1,9 +1,6 @@
|
||||
#
|
||||
# Makefile for CEPH filesystem.
|
||||
#
|
||||
|
||||
ifneq ($(KERNELRELEASE),)
|
||||
|
||||
obj-$(CONFIG_CEPH_LIB) += libceph.o
|
||||
|
||||
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 \
|
||||
ceph_fs.o ceph_strings.o ceph_hash.o \
|
||||
pagevec.o
|
||||
|
||||
else
|
||||
#Otherwise we were called directly from the command
|
||||
# line; invoke the kernel build system.
|
||||
|
||||
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
default: all
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules
|
||||
|
||||
modules_install:
|
||||
$(MAKE) -C $(KERNELDIR) M=$(PWD) CONFIG_CEPH_LIB=m modules_install
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
|
||||
|
||||
endif
|
||||
|
@ -239,7 +239,8 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
|
||||
dccp_update_gsr(sk, seqno);
|
||||
|
||||
if (dh->dccph_type != DCCP_PKT_SYNC &&
|
||||
(ackno != DCCP_PKT_WITHOUT_ACK_SEQ))
|
||||
ackno != DCCP_PKT_WITHOUT_ACK_SEQ &&
|
||||
after48(ackno, dp->dccps_gar))
|
||||
dp->dccps_gar = ackno;
|
||||
} else {
|
||||
unsigned long now = jiffies;
|
||||
|
@ -1556,6 +1556,8 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
|
||||
if (r_len > sizeof(struct linkinfo_dn))
|
||||
r_len = sizeof(struct linkinfo_dn);
|
||||
|
||||
memset(&link, 0, sizeof(link));
|
||||
|
||||
switch(sock->state) {
|
||||
case SS_CONNECTING:
|
||||
link.idn_linkstate = LL_CONNECTING;
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/inet_common.h>
|
||||
#include <linux/stat.h>
|
||||
@ -276,12 +277,12 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||
#endif
|
||||
#ifdef CONFIG_ECONET_AUNUDP
|
||||
struct msghdr udpmsg;
|
||||
struct iovec iov[msg->msg_iovlen+1];
|
||||
struct iovec iov[2];
|
||||
struct aunhdr ah;
|
||||
struct sockaddr_in udpdest;
|
||||
__kernel_size_t size;
|
||||
int i;
|
||||
mm_segment_t oldfs;
|
||||
char *userbuf;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -297,23 +298,14 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||
|
||||
mutex_lock(&econet_mutex);
|
||||
|
||||
if (saddr == NULL) {
|
||||
struct econet_sock *eo = ec_sk(sk);
|
||||
|
||||
addr.station = eo->station;
|
||||
addr.net = eo->net;
|
||||
port = eo->port;
|
||||
cb = eo->cb;
|
||||
} else {
|
||||
if (msg->msg_namelen < sizeof(struct sockaddr_ec)) {
|
||||
mutex_unlock(&econet_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
addr.station = saddr->addr.station;
|
||||
addr.net = saddr->addr.net;
|
||||
port = saddr->port;
|
||||
cb = saddr->cb;
|
||||
}
|
||||
if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) {
|
||||
mutex_unlock(&econet_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
addr.station = saddr->addr.station;
|
||||
addr.net = saddr->addr.net;
|
||||
port = saddr->port;
|
||||
cb = saddr->cb;
|
||||
|
||||
/* Look for a device with the right network number. */
|
||||
dev = net2dev_map[addr.net];
|
||||
@ -328,17 +320,17 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||
}
|
||||
}
|
||||
|
||||
if (len + 15 > dev->mtu) {
|
||||
mutex_unlock(&econet_mutex);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
if (dev->type == ARPHRD_ECONET) {
|
||||
/* Real hardware Econet. We're not worthy etc. */
|
||||
#ifdef CONFIG_ECONET_NATIVE
|
||||
unsigned short proto = 0;
|
||||
int res;
|
||||
|
||||
if (len + 15 > dev->mtu) {
|
||||
mutex_unlock(&econet_mutex);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
dev_hold(dev);
|
||||
|
||||
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,
|
||||
|
||||
eb = (struct ec_cb *)&skb->cb;
|
||||
|
||||
/* BUG: saddr may be NULL */
|
||||
eb->cookie = saddr->cookie;
|
||||
eb->sec = *saddr;
|
||||
eb->sent = ec_tx_done;
|
||||
@ -415,6 +406,11 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||
return -ENETDOWN; /* No socket - can't send */
|
||||
}
|
||||
|
||||
if (len > 32768) {
|
||||
err = -E2BIG;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Make up a UDP datagram and hand it off to some higher intellect. */
|
||||
|
||||
memset(&udpdest, 0, sizeof(udpdest));
|
||||
@ -446,36 +442,26 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||
|
||||
/* tack our header on the front of the iovec */
|
||||
size = sizeof(struct aunhdr);
|
||||
/*
|
||||
* XXX: that is b0rken. We can't mix userland and kernel pointers
|
||||
* in iovec, since on a lot of platforms copy_from_user() will
|
||||
* *not* work with the kernel and userland ones at the same time,
|
||||
* regardless of what we do with set_fs(). And we are talking about
|
||||
* econet-over-ethernet here, so "it's only ARM anyway" doesn't
|
||||
* apply. Any suggestions on fixing that code? -- AV
|
||||
*/
|
||||
iov[0].iov_base = (void *)&ah;
|
||||
iov[0].iov_len = size;
|
||||
for (i = 0; i < msg->msg_iovlen; i++) {
|
||||
void __user *base = msg->msg_iov[i].iov_base;
|
||||
size_t iov_len = msg->msg_iov[i].iov_len;
|
||||
/* Check it now since we switch to KERNEL_DS later. */
|
||||
if (!access_ok(VERIFY_READ, base, iov_len)) {
|
||||
mutex_unlock(&econet_mutex);
|
||||
return -EFAULT;
|
||||
}
|
||||
iov[i+1].iov_base = base;
|
||||
iov[i+1].iov_len = iov_len;
|
||||
size += iov_len;
|
||||
|
||||
userbuf = vmalloc(len);
|
||||
if (userbuf == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
iov[1].iov_base = userbuf;
|
||||
iov[1].iov_len = len;
|
||||
err = memcpy_fromiovec(userbuf, msg->msg_iov, len);
|
||||
if (err)
|
||||
goto error_free_buf;
|
||||
|
||||
/* Get a skbuff (no data, just holds our cb information) */
|
||||
if ((skb = sock_alloc_send_skb(sk, 0,
|
||||
msg->msg_flags & MSG_DONTWAIT,
|
||||
&err)) == NULL) {
|
||||
mutex_unlock(&econet_mutex);
|
||||
return err;
|
||||
}
|
||||
&err)) == NULL)
|
||||
goto error_free_buf;
|
||||
|
||||
eb = (struct ec_cb *)&skb->cb;
|
||||
|
||||
@ -491,7 +477,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||
udpmsg.msg_name = (void *)&udpdest;
|
||||
udpmsg.msg_namelen = sizeof(udpdest);
|
||||
udpmsg.msg_iov = &iov[0];
|
||||
udpmsg.msg_iovlen = msg->msg_iovlen + 1;
|
||||
udpmsg.msg_iovlen = 2;
|
||||
udpmsg.msg_control = NULL;
|
||||
udpmsg.msg_controllen = 0;
|
||||
udpmsg.msg_flags=0;
|
||||
@ -499,9 +485,13 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
|
||||
oldfs = get_fs(); set_fs(KERNEL_DS); /* More privs :-) */
|
||||
err = sock_sendmsg(udpsock, &udpmsg, size);
|
||||
set_fs(oldfs);
|
||||
|
||||
error_free_buf:
|
||||
vfree(userbuf);
|
||||
#else
|
||||
err = -EPROTOTYPE;
|
||||
#endif
|
||||
error:
|
||||
mutex_unlock(&econet_mutex);
|
||||
|
||||
return err;
|
||||
@ -671,6 +661,9 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
|
||||
err = 0;
|
||||
switch (cmd) {
|
||||
case SIOCSIFADDR:
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
edev = dev->ec_ptr;
|
||||
if (edev == NULL) {
|
||||
/* Magic up a new one. */
|
||||
|
@ -133,8 +133,7 @@ int __inet_inherit_port(struct sock *sk, struct sock *child)
|
||||
}
|
||||
}
|
||||
}
|
||||
sk_add_bind_node(child, &tb->owners);
|
||||
inet_csk(child)->icsk_bind_hash = tb;
|
||||
inet_bind_hash(child, tb, port);
|
||||
spin_unlock(&head->lock);
|
||||
|
||||
return 0;
|
||||
|
@ -26,6 +26,8 @@ static int zero;
|
||||
static int tcp_retr1_max = 255;
|
||||
static int ip_local_port_range_min[] = { 1, 1 };
|
||||
static int ip_local_port_range_max[] = { 65535, 65535 };
|
||||
static int tcp_adv_win_scale_min = -31;
|
||||
static int tcp_adv_win_scale_max = 31;
|
||||
|
||||
/* Update system visible IP port range */
|
||||
static void set_local_port_range(int range[2])
|
||||
@ -426,7 +428,9 @@ static struct ctl_table ipv4_table[] = {
|
||||
.data = &sysctl_tcp_adv_win_scale,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = &tcp_adv_win_scale_min,
|
||||
.extra2 = &tcp_adv_win_scale_max,
|
||||
},
|
||||
{
|
||||
.procname = "tcp_tw_reuse",
|
||||
|
@ -2246,7 +2246,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
|
||||
/* Values greater than interface MTU won't take effect. However
|
||||
* at the point when this call is done we typically don't yet
|
||||
* know which interface is going to be used */
|
||||
if (val < 64 || val > MAX_TCP_WINDOW) {
|
||||
if (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
@ -2043,7 +2043,9 @@ get_req:
|
||||
}
|
||||
get_sk:
|
||||
sk_nulls_for_each_from(sk, node) {
|
||||
if (sk->sk_family == st->family && net_eq(sock_net(sk), net)) {
|
||||
if (!net_eq(sock_net(sk), net))
|
||||
continue;
|
||||
if (sk->sk_family == st->family) {
|
||||
cur = sk;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1343,9 +1343,25 @@ static void unix_destruct_scm(struct sk_buff *skb)
|
||||
sock_wfree(skb);
|
||||
}
|
||||
|
||||
#define MAX_RECURSION_LEVEL 4
|
||||
|
||||
static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
{
|
||||
int i;
|
||||
unsigned char max_level = 0;
|
||||
int unix_sock_count = 0;
|
||||
|
||||
for (i = scm->fp->count - 1; i >= 0; i--) {
|
||||
struct sock *sk = unix_get_socket(scm->fp->fp[i]);
|
||||
|
||||
if (sk) {
|
||||
unix_sock_count++;
|
||||
max_level = max(max_level,
|
||||
unix_sk(sk)->recursion_level);
|
||||
}
|
||||
}
|
||||
if (unlikely(max_level > MAX_RECURSION_LEVEL))
|
||||
return -ETOOMANYREFS;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
if (!UNIXCB(skb).fp)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = scm->fp->count-1; i >= 0; i--)
|
||||
unix_inflight(scm->fp->fp[i]);
|
||||
return 0;
|
||||
if (unix_sock_count) {
|
||||
for (i = scm->fp->count - 1; i >= 0; i--)
|
||||
unix_inflight(scm->fp->fp[i]);
|
||||
}
|
||||
return max_level;
|
||||
}
|
||||
|
||||
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,
|
||||
struct sk_buff *skb;
|
||||
long timeo;
|
||||
struct scm_cookie tmp_scm;
|
||||
int max_level;
|
||||
|
||||
if (NULL == siocb->scm)
|
||||
siocb->scm = &tmp_scm;
|
||||
@ -1431,8 +1450,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||
goto out;
|
||||
|
||||
err = unix_scm_to_skb(siocb->scm, skb, true);
|
||||
if (err)
|
||||
if (err < 0)
|
||||
goto out_free;
|
||||
max_level = err + 1;
|
||||
unix_get_secdata(siocb->scm, skb);
|
||||
|
||||
skb_reset_transport_header(skb);
|
||||
@ -1514,6 +1534,8 @@ restart:
|
||||
if (sock_flag(other, SOCK_RCVTSTAMP))
|
||||
__net_timestamp(skb);
|
||||
skb_queue_tail(&other->sk_receive_queue, skb);
|
||||
if (max_level > unix_sk(other)->recursion_level)
|
||||
unix_sk(other)->recursion_level = max_level;
|
||||
unix_state_unlock(other);
|
||||
other->sk_data_ready(other, len);
|
||||
sock_put(other);
|
||||
@ -1544,6 +1566,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||
int sent = 0;
|
||||
struct scm_cookie tmp_scm;
|
||||
bool fds_sent = false;
|
||||
int max_level;
|
||||
|
||||
if (NULL == siocb->scm)
|
||||
siocb->scm = &tmp_scm;
|
||||
@ -1607,10 +1630,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||
|
||||
/* Only send the fds in the first buffer */
|
||||
err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
|
||||
if (err) {
|
||||
if (err < 0) {
|
||||
kfree_skb(skb);
|
||||
goto out_err;
|
||||
}
|
||||
max_level = err + 1;
|
||||
fds_sent = true;
|
||||
|
||||
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,
|
||||
goto pipe_err_free;
|
||||
|
||||
skb_queue_tail(&other->sk_receive_queue, skb);
|
||||
if (max_level > unix_sk(other)->recursion_level)
|
||||
unix_sk(other)->recursion_level = max_level;
|
||||
unix_state_unlock(other);
|
||||
other->sk_data_ready(other, size);
|
||||
sent += size;
|
||||
@ -1845,6 +1871,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
|
||||
unix_state_lock(sk);
|
||||
skb = skb_dequeue(&sk->sk_receive_queue);
|
||||
if (skb == NULL) {
|
||||
unix_sk(sk)->recursion_level = 0;
|
||||
if (copied >= target)
|
||||
goto unlock;
|
||||
|
||||
|
@ -96,7 +96,7 @@ static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
|
||||
unsigned int unix_tot_inflight;
|
||||
|
||||
|
||||
static struct sock *unix_get_socket(struct file *filp)
|
||||
struct sock *unix_get_socket(struct file *filp)
|
||||
{
|
||||
struct sock *u_sock = NULL;
|
||||
struct inode *inode = filp->f_path.dentry->d_inode;
|
||||
@ -259,9 +259,16 @@ static void inc_inflight_move_tail(struct unix_sock *u)
|
||||
}
|
||||
|
||||
static bool gc_in_progress = false;
|
||||
#define UNIX_INFLIGHT_TRIGGER_GC 16000
|
||||
|
||||
void wait_for_unix_gc(void)
|
||||
{
|
||||
/*
|
||||
* If number of inflight sockets is insane,
|
||||
* force a garbage collect right now.
|
||||
*/
|
||||
if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress)
|
||||
unix_gc();
|
||||
wait_event(unix_gc_wait, gc_in_progress == false);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user