diff --git a/net/ipx/Kconfig b/net/ipx/Kconfig
index 02549cb2c3282f5a04ad70214a5cf3f95d1538bf..e9ad0062fbb6a8df3e13182597176016657695b6 100644
--- a/net/ipx/Kconfig
+++ b/net/ipx/Kconfig
@@ -3,7 +3,6 @@
 #
 config IPX
 	tristate "The IPX protocol"
-	depends on BKL # should be fixable
 	select LLC
 	---help---
 	  This is support for the Novell networking protocol, IPX, commonly
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index da3d21c41d9064cb691342dfe23df37460766b84..2731b51923d1f964e3446f0a39ceb5221cd74a56 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -42,7 +42,6 @@
 #include <linux/uio.h>
 #include <linux/slab.h>
 #include <linux/skbuff.h>
-#include <linux/smp_lock.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/string.h>
@@ -1299,7 +1298,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname,
 	int opt;
 	int rc = -EINVAL;
 
-	lock_kernel();
+	lock_sock(sk);
 	if (optlen != sizeof(int))
 		goto out;
 
@@ -1314,7 +1313,7 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname,
 	ipx_sk(sk)->type = opt;
 	rc = 0;
 out:
-	unlock_kernel();
+	release_sock(sk);
 	return rc;
 }
 
@@ -1326,7 +1325,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname,
 	int len;
 	int rc = -ENOPROTOOPT;
 
-	lock_kernel();
+	lock_sock(sk);
 	if (!(level == SOL_IPX && optname == IPX_TYPE))
 		goto out;
 
@@ -1347,7 +1346,7 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname,
 
 	rc = 0;
 out:
-	unlock_kernel();
+	release_sock(sk);
 	return rc;
 }
 
@@ -1396,7 +1395,7 @@ static int ipx_release(struct socket *sock)
 	if (!sk)
 		goto out;
 
-	lock_kernel();
+	lock_sock(sk);
 	if (!sock_flag(sk, SOCK_DEAD))
 		sk->sk_state_change(sk);
 
@@ -1404,7 +1403,7 @@ static int ipx_release(struct socket *sock)
 	sock->sk = NULL;
 	sk_refcnt_debug_release(sk);
 	ipx_destroy_socket(sk);
-	unlock_kernel();
+	release_sock(sk);
 out:
 	return 0;
 }
@@ -1530,11 +1529,12 @@ static int __ipx_bind(struct socket *sock,
 
 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
+	struct sock *sk = sock->sk;
 	int rc;
 
-	lock_kernel();
+	lock_sock(sk);
 	rc = __ipx_bind(sock, uaddr, addr_len);
-	unlock_kernel();
+	release_sock(sk);
 
 	return rc;
 }
@@ -1551,7 +1551,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
 	sk->sk_state	= TCP_CLOSE;
 	sock->state 	= SS_UNCONNECTED;
 
-	lock_kernel();
+	lock_sock(sk);
 	if (addr_len != sizeof(*addr))
 		goto out;
 	addr = (struct sockaddr_ipx *)uaddr;
@@ -1598,7 +1598,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
 		ipxrtr_put(rt);
 	rc = 0;
 out:
-	unlock_kernel();
+	release_sock(sk);
 	return rc;
 }
 
@@ -1614,7 +1614,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
 
 	*uaddr_len = sizeof(struct sockaddr_ipx);
 
-	lock_kernel();
+	lock_sock(sk);
 	if (peer) {
 		rc = -ENOTCONN;
 		if (sk->sk_state != TCP_ESTABLISHED)
@@ -1649,19 +1649,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
 
 	rc = 0;
 out:
-	unlock_kernel();
-	return rc;
-}
-
-static unsigned int ipx_datagram_poll(struct file *file, struct socket *sock,
-			   poll_table *wait)
-{
-	int rc;
-
-	lock_kernel();
-	rc = datagram_poll(file, sock, wait);
-	unlock_kernel();
-
+	release_sock(sk);
 	return rc;
 }
 
@@ -1736,7 +1724,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
 	int rc = -EINVAL;
 	int flags = msg->msg_flags;
 
-	lock_kernel();
+	lock_sock(sk);
 	/* Socket gets bound below anyway */
 /*	if (sk->sk_zapped)
 		return -EIO; */	/* Socket not bound */
@@ -1788,7 +1776,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
 	if (rc >= 0)
 		rc = len;
 out:
-	unlock_kernel();
+	release_sock(sk);
 	return rc;
 }
 
@@ -1803,7 +1791,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
 	struct sk_buff *skb;
 	int copied, rc;
 
-	lock_kernel();
+	lock_sock(sk);
 	/* put the autobinding in */
 	if (!ipxs->port) {
 		struct sockaddr_ipx uaddr;
@@ -1862,7 +1850,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
 out_free:
 	skb_free_datagram(sk, skb);
 out:
-	unlock_kernel();
+	release_sock(sk);
 	return rc;
 }
 
@@ -1874,7 +1862,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 	struct sock *sk = sock->sk;
 	void __user *argp = (void __user *)arg;
 
-	lock_kernel();
+	lock_sock(sk);
 	switch (cmd) {
 	case TIOCOUTQ:
 		amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
@@ -1937,7 +1925,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 		rc = -ENOIOCTLCMD;
 		break;
 	}
-	unlock_kernel();
+	release_sock(sk);
 
 	return rc;
 }
@@ -1984,7 +1972,7 @@ static const struct proto_ops ipx_dgram_ops = {
 	.socketpair	= sock_no_socketpair,
 	.accept		= sock_no_accept,
 	.getname	= ipx_getname,
-	.poll		= ipx_datagram_poll,
+	.poll		= datagram_poll,
 	.ioctl		= ipx_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= ipx_compat_ioctl,