Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion drivers/gpu/drm/drm_atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
if (!state->planes)
goto fail;

/*
* Because drm_atomic_state can be committed asynchronously we need our
* own reference and cannot rely on the on implied by drm_file in the
* ioctl call.
*/
drm_dev_get(dev);
state->dev = dev;

drm_dbg_atomic(dev, "Allocated atomic state %p\n", state);
Expand Down Expand Up @@ -299,7 +305,8 @@ EXPORT_SYMBOL(drm_atomic_state_clear);
void __drm_atomic_state_free(struct kref *ref)
{
struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
struct drm_mode_config *config = &state->dev->mode_config;
struct drm_device *dev = state->dev;
struct drm_mode_config *config = &dev->mode_config;

drm_atomic_state_clear(state);

Expand All @@ -311,6 +318,8 @@ void __drm_atomic_state_free(struct kref *ref)
drm_atomic_state_default_release(state);
kfree(state);
}

drm_dev_put(dev);
}
EXPORT_SYMBOL(__drm_atomic_state_free);

Expand Down
255 changes: 132 additions & 123 deletions drivers/infiniband/core/cma.c
Original file line number Diff line number Diff line change
Expand Up @@ -3493,121 +3493,6 @@ static int cma_resolve_ib_addr(struct rdma_id_private *id_priv)
return ret;
}

static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
const struct sockaddr *dst_addr)
{
struct sockaddr_storage zero_sock = {};

if (src_addr && src_addr->sa_family)
return rdma_bind_addr(id, src_addr);

/*
* When the src_addr is not specified, automatically supply an any addr
*/
zero_sock.ss_family = dst_addr->sa_family;
if (IS_ENABLED(CONFIG_IPV6) && dst_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *src_addr6 =
(struct sockaddr_in6 *)&zero_sock;
struct sockaddr_in6 *dst_addr6 =
(struct sockaddr_in6 *)dst_addr;

src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id;
if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
id->route.addr.dev_addr.bound_dev_if =
dst_addr6->sin6_scope_id;
} else if (dst_addr->sa_family == AF_IB) {
((struct sockaddr_ib *)&zero_sock)->sib_pkey =
((struct sockaddr_ib *)dst_addr)->sib_pkey;
}
return rdma_bind_addr(id, (struct sockaddr *)&zero_sock);
}

/*
* If required, resolve the source address for bind and leave the id_priv in
* state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior
* calls made by ULP, a previously bound ID will not be re-bound and src_addr is
* ignored.
*/
static int resolve_prepare_src(struct rdma_id_private *id_priv,
struct sockaddr *src_addr,
const struct sockaddr *dst_addr)
{
int ret;

memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) {
/* For a well behaved ULP state will be RDMA_CM_IDLE */
ret = cma_bind_addr(&id_priv->id, src_addr, dst_addr);
if (ret)
goto err_dst;
if (WARN_ON(!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND,
RDMA_CM_ADDR_QUERY))) {
ret = -EINVAL;
goto err_dst;
}
}

if (cma_family(id_priv) != dst_addr->sa_family) {
ret = -EINVAL;
goto err_state;
}
return 0;

err_state:
cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
err_dst:
memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr));
return ret;
}

int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
const struct sockaddr *dst_addr, unsigned long timeout_ms)
{
struct rdma_id_private *id_priv =
container_of(id, struct rdma_id_private, id);
int ret;

ret = resolve_prepare_src(id_priv, src_addr, dst_addr);
if (ret)
return ret;

if (cma_any_addr(dst_addr)) {
ret = cma_resolve_loopback(id_priv);
} else {
if (dst_addr->sa_family == AF_IB) {
ret = cma_resolve_ib_addr(id_priv);
} else {
/*
* The FSM can return back to RDMA_CM_ADDR_BOUND after
* rdma_resolve_ip() is called, eg through the error
* path in addr_handler(). If this happens the existing
* request must be canceled before issuing a new one.
* Since canceling a request is a bit slow and this
* oddball path is rare, keep track once a request has
* been issued. The track turns out to be a permanent
* state since this is the only cancel as it is
* immediately before rdma_resolve_ip().
*/
if (id_priv->used_resolve_ip)
rdma_addr_cancel(&id->route.addr.dev_addr);
else
id_priv->used_resolve_ip = 1;
ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr,
&id->route.addr.dev_addr,
timeout_ms, addr_handler,
false, id_priv);
}
}
if (ret)
goto err;

return 0;
err:
cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
return ret;
}
EXPORT_SYMBOL(rdma_resolve_addr);

int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse)
{
struct rdma_id_private *id_priv;
Expand Down Expand Up @@ -4010,27 +3895,26 @@ int rdma_listen(struct rdma_cm_id *id, int backlog)
}
EXPORT_SYMBOL(rdma_listen);

int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
static int rdma_bind_addr_dst(struct rdma_id_private *id_priv,
struct sockaddr *addr, const struct sockaddr *daddr)
{
struct rdma_id_private *id_priv;
struct sockaddr *id_daddr;
int ret;
struct sockaddr *daddr;

if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6 &&
addr->sa_family != AF_IB)
return -EAFNOSUPPORT;

id_priv = container_of(id, struct rdma_id_private, id);
if (!cma_comp_exch(id_priv, RDMA_CM_IDLE, RDMA_CM_ADDR_BOUND))
return -EINVAL;

ret = cma_check_linklocal(&id->route.addr.dev_addr, addr);
ret = cma_check_linklocal(&id_priv->id.route.addr.dev_addr, addr);
if (ret)
goto err1;

memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr));
if (!cma_any_addr(addr)) {
ret = cma_translate_addr(addr, &id->route.addr.dev_addr);
ret = cma_translate_addr(addr, &id_priv->id.route.addr.dev_addr);
if (ret)
goto err1;

Expand All @@ -4050,8 +3934,10 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
}
#endif
}
daddr = cma_dst_addr(id_priv);
daddr->sa_family = addr->sa_family;
id_daddr = cma_dst_addr(id_priv);
if (daddr != id_daddr)
memcpy(id_daddr, daddr, rdma_addr_size(addr));
id_daddr->sa_family = addr->sa_family;

ret = cma_get_port(id_priv);
if (ret)
Expand All @@ -4067,6 +3953,129 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_IDLE);
return ret;
}

static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
const struct sockaddr *dst_addr)
{
struct rdma_id_private *id_priv =
container_of(id, struct rdma_id_private, id);
struct sockaddr_storage zero_sock = {};

if (src_addr && src_addr->sa_family)
return rdma_bind_addr_dst(id_priv, src_addr, dst_addr);

/*
* When the src_addr is not specified, automatically supply an any addr
*/
zero_sock.ss_family = dst_addr->sa_family;
if (IS_ENABLED(CONFIG_IPV6) && dst_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *src_addr6 =
(struct sockaddr_in6 *)&zero_sock;
struct sockaddr_in6 *dst_addr6 =
(struct sockaddr_in6 *)dst_addr;

src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id;
if (ipv6_addr_type(&dst_addr6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
id->route.addr.dev_addr.bound_dev_if =
dst_addr6->sin6_scope_id;
} else if (dst_addr->sa_family == AF_IB) {
((struct sockaddr_ib *)&zero_sock)->sib_pkey =
((struct sockaddr_ib *)dst_addr)->sib_pkey;
}
return rdma_bind_addr_dst(id_priv, (struct sockaddr *)&zero_sock, dst_addr);
}

/*
* If required, resolve the source address for bind and leave the id_priv in
* state RDMA_CM_ADDR_BOUND. This oddly uses the state to determine the prior
* calls made by ULP, a previously bound ID will not be re-bound and src_addr is
* ignored.
*/
static int resolve_prepare_src(struct rdma_id_private *id_priv,
struct sockaddr *src_addr,
const struct sockaddr *dst_addr)
{
int ret;

if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) {
/* For a well behaved ULP state will be RDMA_CM_IDLE */
ret = cma_bind_addr(&id_priv->id, src_addr, dst_addr);
if (ret)
return ret;
if (WARN_ON(!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND,
RDMA_CM_ADDR_QUERY)))
return -EINVAL;

} else {
memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr));
}

if (cma_family(id_priv) != dst_addr->sa_family) {
ret = -EINVAL;
goto err_state;
}
return 0;

err_state:
cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
return ret;
}

int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
const struct sockaddr *dst_addr, unsigned long timeout_ms)
{
struct rdma_id_private *id_priv =
container_of(id, struct rdma_id_private, id);
int ret;

ret = resolve_prepare_src(id_priv, src_addr, dst_addr);
if (ret)
return ret;

if (cma_any_addr(dst_addr)) {
ret = cma_resolve_loopback(id_priv);
} else {
if (dst_addr->sa_family == AF_IB) {
ret = cma_resolve_ib_addr(id_priv);
} else {
/*
* The FSM can return back to RDMA_CM_ADDR_BOUND after
* rdma_resolve_ip() is called, eg through the error
* path in addr_handler(). If this happens the existing
* request must be canceled before issuing a new one.
* Since canceling a request is a bit slow and this
* oddball path is rare, keep track once a request has
* been issued. The track turns out to be a permanent
* state since this is the only cancel as it is
* immediately before rdma_resolve_ip().
*/
if (id_priv->used_resolve_ip)
rdma_addr_cancel(&id->route.addr.dev_addr);
else
id_priv->used_resolve_ip = 1;
ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr,
&id->route.addr.dev_addr,
timeout_ms, addr_handler,
false, id_priv);
}
}
if (ret)
goto err;

return 0;
err:
cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
return ret;
}
EXPORT_SYMBOL(rdma_resolve_addr);

int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
{
struct rdma_id_private *id_priv =
container_of(id, struct rdma_id_private, id);

return rdma_bind_addr_dst(id_priv, addr, cma_dst_addr(id_priv));
}
EXPORT_SYMBOL(rdma_bind_addr);

static int cma_format_hdr(void *hdr, struct rdma_id_private *id_priv)
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,6 @@ area_cache_get(struct nfp_cpp *cpp, u32 id,
}

/* Adjust the start address to be cache size aligned */
cache->id = id;
cache->addr = addr & ~(u64)(cache->size - 1);

/* Re-init to the new ID and address */
Expand All @@ -894,6 +893,8 @@ area_cache_get(struct nfp_cpp *cpp, u32 id,
return NULL;
}

cache->id = id;

exit:
/* Adjust offset */
*offset = addr - cache->addr;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/slip/slip.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ static void sl_tx_timeout(struct net_device *dev, unsigned int txqueue)
spin_lock(&sl->lock);

if (netif_queue_stopped(dev)) {
if (!netif_running(dev))
if (!netif_running(dev) || !sl->tty)
goto out;

/* May be we must check transmitter timeout here ?
Expand Down
Loading