summaryrefslogtreecommitdiff
path: root/include/linux/atmdev.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/atmdev.h')
-rw-r--r--include/linux/atmdev.h46
1 files changed, 31 insertions, 15 deletions
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index c1da539f5e28..70807c679f1a 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* atmdev.h - ATM device driver declarations and various related items */
#ifndef LINUX_ATMDEV_H
#define LINUX_ATMDEV_H
@@ -11,6 +12,7 @@
#include <linux/uio.h>
#include <net/sock.h>
#include <linux/atomic.h>
+#include <linux/refcount.h>
#include <uapi/linux/atmdev.h>
#ifdef CONFIG_PROC_FS
@@ -149,7 +151,7 @@ struct atm_dev {
const char *type; /* device type name */
int number; /* device index */
void *dev_data; /* per-device data */
- void *phy_data; /* private PHY date */
+ void *phy_data; /* private PHY data */
unsigned long flags; /* device flags (ATM_DF_*) */
struct list_head local; /* local ATM addresses */
struct list_head lecs; /* LECS ATM addresses learned via ILMI */
@@ -158,7 +160,7 @@ struct atm_dev {
struct k_atm_dev_stats stats; /* statistics */
char signal; /* signal status (ATM_PHY_SIG_*) */
int link_rate; /* link rate (default: OC3) */
- atomic_t refcnt; /* reference count */
+ refcount_t refcnt; /* reference count */
spinlock_t lock; /* protect internal members */
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry; /* proc entry */
@@ -174,11 +176,6 @@ struct atm_dev {
#define ATM_OF_IMMED 1 /* Attempt immediate delivery */
#define ATM_OF_INRATE 2 /* Attempt in-rate delivery */
-
-/*
- * ioctl, getsockopt, and setsockopt are optional and can be set to NULL.
- */
-
struct atmdev_ops { /* only send is required */
void (*dev_close)(struct atm_dev *dev);
int (*open)(struct atm_vcc *vcc);
@@ -188,11 +185,9 @@ struct atmdev_ops { /* only send is required */
int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
void __user *arg);
#endif
- int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,int optlen);
- int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
- void __user *optval,unsigned int optlen);
+ int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+ int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
void (*phy_put)(struct atm_dev *dev,unsigned char value,
unsigned long addr);
@@ -212,7 +207,8 @@ struct atmphy_ops {
struct atm_skb_data {
struct atm_vcc *vcc; /* ATM VCC */
unsigned long atm_options; /* ATM layer options */
-};
+ unsigned int acct_truesize; /* truesize accounted to vcc */
+} __packed;
#define VCC_HTABLE_SIZE 32
@@ -239,6 +235,26 @@ void vcc_insert_socket(struct sock *sk);
void atm_dev_release_vccs(struct atm_dev *dev);
+static inline void atm_account_tx(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+ /*
+ * Because ATM skbs may not belong to a sock (and we don't
+ * necessarily want to), skb->truesize may be adjusted,
+ * escaping the hack in pskb_expand_head() which avoids
+ * doing so for some cases. So stash the value of truesize
+ * at the time we accounted it, and atm_pop_raw() can use
+ * that value later, in case it changes.
+ */
+ refcount_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
+ ATM_SKB(skb)->acct_truesize = skb->truesize;
+ ATM_SKB(skb)->atm_options = vcc->atm_options;
+}
+
+static inline void atm_return_tx(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+ WARN_ON_ONCE(refcount_sub_and_test(ATM_SKB(skb)->acct_truesize,
+ &sk_atm(vcc)->sk_wmem_alloc));
+}
static inline void atm_force_charge(struct atm_vcc *vcc,int truesize)
{
@@ -254,20 +270,20 @@ static inline void atm_return(struct atm_vcc *vcc,int truesize)
static inline int atm_may_send(struct atm_vcc *vcc,unsigned int size)
{
- return (size + atomic_read(&sk_atm(vcc)->sk_wmem_alloc)) <
+ return (size + refcount_read(&sk_atm(vcc)->sk_wmem_alloc)) <
sk_atm(vcc)->sk_sndbuf;
}
static inline void atm_dev_hold(struct atm_dev *dev)
{
- atomic_inc(&dev->refcnt);
+ refcount_inc(&dev->refcnt);
}
static inline void atm_dev_put(struct atm_dev *dev)
{
- if (atomic_dec_and_test(&dev->refcnt)) {
+ if (refcount_dec_and_test(&dev->refcnt)) {
BUG_ON(!test_bit(ATM_DF_REMOVED, &dev->flags));
if (dev->ops->dev_close)
dev->ops->dev_close(dev);