Module: xenomai-gch
Branch: for-forge
Commit: ae47e0715ced536bb273bf8691b9fc32be90e552
URL:    
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=ae47e0715ced536bb273bf8691b9fc32be90e552

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Wed Sep 30 22:47:09 2015 +0200

rtnet/stack_mgr: rework packet type locking

Use module count to lock packet types rather than a reference count with
a loop blocking module unload.

---

 kernel/drivers/net/stack/include/stack_mgr.h |   14 +++++++++-----
 kernel/drivers/net/stack/ipv4/arp.c          |    6 +-----
 kernel/drivers/net/stack/ipv4/ip_output.c    |    6 +-----
 kernel/drivers/net/stack/packet/af_packet.c  |   10 ++++------
 kernel/drivers/net/stack/rtcfg/rtcfg_frame.c |    6 +-----
 kernel/drivers/net/stack/rtmac/rtmac_proto.c |    6 +-----
 kernel/drivers/net/stack/stack_mgr.c         |   19 ++++++-------------
 7 files changed, 23 insertions(+), 44 deletions(-)

diff --git a/kernel/drivers/net/stack/include/stack_mgr.h 
b/kernel/drivers/net/stack/include/stack_mgr.h
index 871bbd4..4265252 100644
--- a/kernel/drivers/net/stack/include/stack_mgr.h
+++ b/kernel/drivers/net/stack/include/stack_mgr.h
@@ -51,21 +51,25 @@ struct rtpacket_type {
                                        struct rtpacket_type *);
     bool                (*trylock)(struct rtpacket_type *);
     void                (*unlock)(struct rtpacket_type *);
+
+    struct module      *owner;
 };
 
 
-int rtdev_add_pack(struct rtpacket_type *pt);
-int rtdev_remove_pack(struct rtpacket_type *pt);
+int __rtdev_add_pack(struct rtpacket_type *pt, struct module *module);
+#define rtdev_add_pack(pt) \
+    __rtdev_add_pack(pt, THIS_MODULE)
+
+void rtdev_remove_pack(struct rtpacket_type *pt);
 
 static inline bool rtdev_lock_pack(struct rtpacket_type *pt)
 {
-    ++pt->refcount;
-    return true;
+    return try_module_get(pt->owner);
 }
 
 static inline void rtdev_unlock_pack(struct rtpacket_type *pt)
 {
-    --pt->refcount;
+    module_put(pt->owner);
 }
 
 void rt_stack_connect(struct rtnet_device *rtdev, struct rtnet_mgr *mgr);
diff --git a/kernel/drivers/net/stack/ipv4/arp.c 
b/kernel/drivers/net/stack/ipv4/arp.c
index 98c010d..d6e074a 100644
--- a/kernel/drivers/net/stack/ipv4/arp.c
+++ b/kernel/drivers/net/stack/ipv4/arp.c
@@ -216,9 +216,5 @@ void __init rt_arp_init(void)
  */
 void rt_arp_release(void)
 {
-    while (rtdev_remove_pack(&arp_packet_type) == -EAGAIN) {
-       printk("RTnet ARP: waiting for protocol unregistration\n");
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(1*HZ); /* wait a second */
-    }
+    rtdev_remove_pack(&arp_packet_type);
 }
diff --git a/kernel/drivers/net/stack/ipv4/ip_output.c 
b/kernel/drivers/net/stack/ipv4/ip_output.c
index 89ca085..b498526 100644
--- a/kernel/drivers/net/stack/ipv4/ip_output.c
+++ b/kernel/drivers/net/stack/ipv4/ip_output.c
@@ -275,10 +275,6 @@ void __init rt_ip_init(void)
  */
 void rt_ip_release(void)
 {
-    while (rtdev_remove_pack(&ip_packet_type) == -EAGAIN) {
-       printk("RTnet IP: waiting for protocol unregistration\n");
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(1*HZ); /* wait a second */
-    }
+    rtdev_remove_pack(&ip_packet_type);
     rt_ip_fragment_cleanup();
 }
diff --git a/kernel/drivers/net/stack/packet/af_packet.c 
b/kernel/drivers/net/stack/packet/af_packet.c
index b4a18c2..faddd18 100644
--- a/kernel/drivers/net/stack/packet/af_packet.c
+++ b/kernel/drivers/net/stack/packet/af_packet.c
@@ -85,7 +85,7 @@ static bool rt_packet_trylock(struct rtpacket_type *pt)
     if (rtdm_fd_lock(fd) < 0)
        return false;
 
-    return rtdev_lock_pack(pt);
+    return true;
 }
 
 static void rt_packet_unlock(struct rtpacket_type *pt)
@@ -93,7 +93,7 @@ static void rt_packet_unlock(struct rtpacket_type *pt)
     struct rtsocket *sock   = container_of(pt, struct rtsocket,
                                           prot.packet.packet_type);
     struct rtdm_fd *fd = rtdm_private_to_fd(sock);
-    rtdev_unlock_pack(pt);
+
     rtdm_fd_unlock(fd);
 }
 
@@ -119,10 +119,8 @@ static int rt_packet_bind(struct rtsocket *sock, const 
struct sockaddr *addr,
     rtdm_lock_get_irqsave(&sock->param_lock, context);
 
     /* release existing binding */
-    if ((pt->type != 0) && ((ret = rtdev_remove_pack(pt)) < 0)) {
-       rtdm_lock_put_irqrestore(&sock->param_lock, context);
-       return ret;
-    }
+    if (pt->type != 0)
+           rtdev_remove_pack(pt);
 
     pt->type = new_type;
     sock->prot.packet.ifindex = sll->sll_ifindex;
diff --git a/kernel/drivers/net/stack/rtcfg/rtcfg_frame.c 
b/kernel/drivers/net/stack/rtcfg/rtcfg_frame.c
index 7ca775d..4725a01 100644
--- a/kernel/drivers/net/stack/rtcfg/rtcfg_frame.c
+++ b/kernel/drivers/net/stack/rtcfg/rtcfg_frame.c
@@ -572,11 +572,7 @@ void rtcfg_cleanup_frames(void)
     struct rtskb *rtskb;
 
 
-    while (rtdev_remove_pack(&rtcfg_packet_type) == -EAGAIN) {
-       RTCFG_DEBUG(3, "RTcfg: waiting for protocol unregistration\n");
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(1*HZ); /* wait a second */
-    }
+    rtdev_remove_pack(&rtcfg_packet_type);
 
     rtdm_event_destroy(&rx_event);
     rtdm_task_join_nrt(&rx_task, 100);
diff --git a/kernel/drivers/net/stack/rtmac/rtmac_proto.c 
b/kernel/drivers/net/stack/rtmac/rtmac_proto.c
index 089214c..deaf733 100644
--- a/kernel/drivers/net/stack/rtmac/rtmac_proto.c
+++ b/kernel/drivers/net/stack/rtmac/rtmac_proto.c
@@ -73,9 +73,5 @@ struct rtpacket_type rtmac_packet_type = {
 
 void rtmac_proto_release(void)
 {
-    while (rtdev_remove_pack(&rtmac_packet_type) == -EAGAIN) {
-        rtdm_printk("RTmac: waiting for protocol unregistration\n");
-        set_current_state(TASK_UNINTERRUPTIBLE);
-        schedule_timeout(1*HZ); /* wait a second */
-    }
+    rtdev_remove_pack(&rtmac_packet_type);
 }
diff --git a/kernel/drivers/net/stack/stack_mgr.c 
b/kernel/drivers/net/stack/stack_mgr.c
index 6c86819..9804ec7 100644
--- a/kernel/drivers/net/stack/stack_mgr.c
+++ b/kernel/drivers/net/stack/stack_mgr.c
@@ -51,7 +51,7 @@ DEFINE_RTDM_LOCK(rt_packets_lock);
  *  rtdev_add_pack:         add protocol (Layer 3)
  *  @pt:                    the new protocol
  */
-int rtdev_add_pack(struct rtpacket_type *pt)
+int __rtdev_add_pack(struct rtpacket_type *pt, struct module *module)
 {
     int                     ret = 0;
     rtdm_lockctx_t          context;
@@ -62,6 +62,7 @@ int rtdev_add_pack(struct rtpacket_type *pt)
        pt->trylock = rtdev_lock_pack;
     if (pt->unlock == NULL)
        pt->unlock = rtdev_unlock_pack;
+    pt->owner = module;
 
     rtdm_lock_get_irqsave(&rt_packets_lock, context);
 
@@ -80,31 +81,23 @@ int rtdev_add_pack(struct rtpacket_type *pt)
     return ret;
 }
 
-EXPORT_SYMBOL_GPL(rtdev_add_pack);
+EXPORT_SYMBOL_GPL(__rtdev_add_pack);
 
 
 /***
  *  rtdev_remove_pack:  remove protocol (Layer 3)
  *  @pt:                protocol
  */
-int rtdev_remove_pack(struct rtpacket_type *pt)
+void rtdev_remove_pack(struct rtpacket_type *pt)
 {
     rtdm_lockctx_t  context;
-    int             ret = 0;
 
 
-    RTNET_ASSERT(pt != NULL, return -EINVAL;);
+    RTNET_ASSERT(pt != NULL, return;);
 
     rtdm_lock_get_irqsave(&rt_packets_lock, context);
-
-    if (pt->refcount > 0)
-       ret = -EAGAIN;
-    else
-       list_del(&pt->list_entry);
-
+    list_del(&pt->list_entry);
     rtdm_lock_put_irqrestore(&rt_packets_lock, context);
-
-    return ret;
 }
 
 EXPORT_SYMBOL_GPL(rtdev_remove_pack);


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to