rds_trans_put(rs->rs_transport);
sock->sk = NULL;
- sock_put(sk);
+ if ((atomic_read(&sk->sk_refcnt) == 0)) {
+ printk(KERN_CRIT "zero refcnt on sock put release\n");
+ WARN_ON(1);
+ }
+
+ if (atomic_dec_and_test(&sk->sk_refcnt)) {
+ if (rs->poison != 0xABABABAB) {
+ printk(KERN_CRIT "bad poison on put release %x\n", rs->poison);
+ WARN_ON(1);
+ }
+ rs->poison = 0xDEADBEEF;
+ sk_free(sk);
+ }
out:
return 0;
}
INIT_LIST_HEAD(&rs->rs_cong_list);
spin_lock_init(&rs->rs_rdma_lock);
rs->rs_rdma_keys = RB_ROOT;
+ rs->poison = 0xABABABAB;
+
+ if (rs->rs_bound_addr) {
+printk(KERN_CRIT "bound addr %x at create\n", rs->rs_bound_addr);
+ }
spin_lock_irqsave(&rds_sock_lock, flags);
list_add_tail(&rs->rs_item, &rds_sock_list);
return __rds_create(sock, sk, protocol);
}
+void debug_sock_hold(struct sock *sk)
+{
+ struct rds_sock *rs = rds_sk_to_rs(sk);
+ if ((atomic_read(&sk->sk_refcnt) == 0)) {
+ printk(KERN_CRIT "zero refcnt on sock hold\n");
+ WARN_ON(1);
+ }
+ if (rs->poison != 0xABABABAB) {
+ printk(KERN_CRIT "bad poison on hold %x\n", rs->poison);
+ WARN_ON(1);
+ }
+ sock_hold(sk);
+}
+
+
void rds_sock_addref(struct rds_sock *rs)
{
- sock_hold(rds_rs_to_sk(rs));
+ debug_sock_hold(rds_rs_to_sk(rs));
+}
+
+void debug_sock_put(struct sock *sk)
+{
+ if ((atomic_read(&sk->sk_refcnt) == 0)) {
+ printk(KERN_CRIT "zero refcnt on sock put\n");
+ WARN_ON(1);
+ }
+ if (atomic_dec_and_test(&sk->sk_refcnt)) {
+ struct rds_sock *rs = rds_sk_to_rs(sk);
+ if (rs->poison != 0xABABABAB) {
+ printk(KERN_CRIT "bad poison on put %x\n", rs->poison);
+ WARN_ON(1);
+ }
+ rs->poison = 0xDEADBEEF;
+ sk_free(sk);
+ }
}
+
void rds_sock_put(struct rds_sock *rs)
{
- sock_put(rds_rs_to_sk(rs));
+ debug_sock_put(rds_rs_to_sk(rs));
}
static struct net_proto_family rds_family_ops = {
/* Socket options - in case there will be more */
unsigned char rs_recverr,
rs_cong_monitor;
+ int poison;
};
static inline struct rds_sock *rds_sk_to_rs(const struct sock *sk)
}
extern wait_queue_head_t rds_poll_waitq;
+void debug_sock_hold(struct sock *sock);
+void debug_sock_put(struct sock *sock);
/* bind.c */
int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len);
&& ro->op_active && ro->op_notify && ro->op_notifier) {
notifier = ro->op_notifier;
rs = rm->m_rs;
- sock_hold(rds_rs_to_sk(rs));
+ debug_sock_hold(rds_rs_to_sk(rs));
notifier->n_status = status;
spin_lock(&rs->rs_lock);
if (rs) {
rds_wake_sk_sleep(rs);
- sock_put(rds_rs_to_sk(rs));
+ debug_sock_put(rds_rs_to_sk(rs));
}
}
EXPORT_SYMBOL_GPL(rds_rdma_send_complete);
&& ao->op_active && ao->op_notify && ao->op_notifier) {
notifier = ao->op_notifier;
rs = rm->m_rs;
- sock_hold(rds_rs_to_sk(rs));
+ debug_sock_hold(rds_rs_to_sk(rs));
notifier->n_status = status;
spin_lock(&rs->rs_lock);
if (rs) {
rds_wake_sk_sleep(rs);
- sock_put(rds_rs_to_sk(rs));
+ debug_sock_put(rds_rs_to_sk(rs));
}
}
EXPORT_SYMBOL_GPL(rds_atomic_send_complete);
if (rs != rm->m_rs) {
if (rs) {
rds_wake_sk_sleep(rs);
- sock_put(rds_rs_to_sk(rs));
+ debug_sock_put(rds_rs_to_sk(rs));
}
rs = rm->m_rs;
- sock_hold(rds_rs_to_sk(rs));
+ debug_sock_hold(rds_rs_to_sk(rs));
}
spin_lock(&rs->rs_lock);
if (rs) {
rds_wake_sk_sleep(rs);
- sock_put(rds_rs_to_sk(rs));
+ debug_sock_put(rds_rs_to_sk(rs));
}
}