Merge tag 'v4.9.8' into android-4.9

This is the 4.9.8 stable release
This commit is contained in:
Dmitry Shmidt
2017-02-06 13:13:30 -08:00
123 changed files with 1012 additions and 517 deletions

View File

@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 6
SUBLEVEL = 8
EXTRAVERSION =
NAME = Roaring Lionus

View File

@@ -26,7 +26,9 @@ static inline void __delay(unsigned long loops)
" lp 1f \n"
" nop \n"
"1: \n"
: : "r"(loops));
:
: "r"(loops)
: "lp_count");
}
extern void __bad_udelay(void);

View File

@@ -241,8 +241,9 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs,
if (state.fault)
goto fault;
/* clear any remanants of delay slot */
if (delay_mode(regs)) {
regs->ret = regs->bta;
regs->ret = regs->bta ~1U;
regs->status32 &= ~STATUS_DE_MASK;
} else {
regs->ret += state.instr_len;

View File

@@ -6,7 +6,7 @@
#endif
#include <linux/compiler.h>
#include <asm/types.h> /* for BITS_PER_LONG/SHIFT_PER_LONG */
#include <asm/types.h>
#include <asm/byteorder.h>
#include <asm/barrier.h>
#include <linux/atomic.h>
@@ -17,6 +17,12 @@
* to include/asm-i386/bitops.h or kerneldoc
*/
#if __BITS_PER_LONG == 64
#define SHIFT_PER_LONG 6
#else
#define SHIFT_PER_LONG 5
#endif
#define CHOP_SHIFTCOUNT(x) (((unsigned long) (x)) & (BITS_PER_LONG - 1))

View File

@@ -3,10 +3,8 @@
#if defined(__LP64__)
#define __BITS_PER_LONG 64
#define SHIFT_PER_LONG 6
#else
#define __BITS_PER_LONG 32
#define SHIFT_PER_LONG 5
#endif
#include <asm-generic/bitsperlong.h>

View File

@@ -1,6 +1,7 @@
#ifndef _PARISC_SWAB_H
#define _PARISC_SWAB_H
#include <asm/bitsperlong.h>
#include <linux/types.h>
#include <linux/compiler.h>
@@ -38,7 +39,7 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
}
#define __arch_swab32 __arch_swab32
#if BITS_PER_LONG > 32
#if __BITS_PER_LONG > 32
/*
** From "PA-RISC 2.0 Architecture", HP Professional Books.
** See Appendix I page 8 , "Endian Byte Swapping".
@@ -61,6 +62,6 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
return x;
}
#define __arch_swab64 __arch_swab64
#endif /* BITS_PER_LONG > 32 */
#endif /* __BITS_PER_LONG > 32 */
#endif /* _PARISC_SWAB_H */

View File

@@ -963,6 +963,11 @@ static int s390_fpregs_set(struct task_struct *target,
if (target == current)
save_fpu_regs();
if (MACHINE_HAS_VX)
convert_vx_to_fp(fprs, target->thread.fpu.vxrs);
else
memcpy(&fprs, target->thread.fpu.fprs, sizeof(fprs));
/* If setting FPC, must validate it first. */
if (count > 0 && pos < offsetof(s390_fp_regs, fprs)) {
u32 ufpc[2] = { target->thread.fpu.fpc, 0 };
@@ -1067,6 +1072,9 @@ static int s390_vxrs_low_set(struct task_struct *target,
if (target == current)
save_fpu_regs();
for (i = 0; i < __NUM_VXRS_LOW; i++)
vxrs[i] = *((__u64 *)(target->thread.fpu.vxrs + i) + 1);
rc = user_regset_copyin(&pos, &count, &kbuf, &ubuf, vxrs, 0, -1);
if (rc == 0)
for (i = 0; i < __NUM_VXRS_LOW; i++)

View File

@@ -202,7 +202,7 @@ static inline pgste_t ptep_xchg_start(struct mm_struct *mm,
return pgste;
}
static inline void ptep_xchg_commit(struct mm_struct *mm,
static inline pte_t ptep_xchg_commit(struct mm_struct *mm,
unsigned long addr, pte_t *ptep,
pgste_t pgste, pte_t old, pte_t new)
{
@@ -220,6 +220,7 @@ static inline void ptep_xchg_commit(struct mm_struct *mm,
} else {
*ptep = new;
}
return old;
}
pte_t ptep_xchg_direct(struct mm_struct *mm, unsigned long addr,
@@ -231,7 +232,7 @@ pte_t ptep_xchg_direct(struct mm_struct *mm, unsigned long addr,
preempt_disable();
pgste = ptep_xchg_start(mm, addr, ptep);
old = ptep_flush_direct(mm, addr, ptep);
ptep_xchg_commit(mm, addr, ptep, pgste, old, new);
old = ptep_xchg_commit(mm, addr, ptep, pgste, old, new);
preempt_enable();
return old;
}
@@ -246,7 +247,7 @@ pte_t ptep_xchg_lazy(struct mm_struct *mm, unsigned long addr,
preempt_disable();
pgste = ptep_xchg_start(mm, addr, ptep);
old = ptep_flush_lazy(mm, addr, ptep);
ptep_xchg_commit(mm, addr, ptep, pgste, old, new);
old = ptep_xchg_commit(mm, addr, ptep, pgste, old, new);
preempt_enable();
return old;
}

View File

@@ -111,7 +111,7 @@ static int tile_gpr_set(struct task_struct *target,
const void *kbuf, const void __user *ubuf)
{
int ret;
struct pt_regs regs;
struct pt_regs regs = *task_pt_regs(target);
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &regs, 0,
sizeof(regs));

View File

@@ -233,7 +233,7 @@ static int __init mlxplat_init(void)
return 0;
fail_platform_mux_register:
for (i--; i > 0 ; i--)
while (--i >= 0)
platform_device_unregister(priv->pdev_mux[i]);
platform_device_unregister(priv->pdev_i2c);
fail_alloc:

View File

@@ -410,14 +410,14 @@ static ssize_t show_valid_zones(struct device *dev,
sprintf(buf, "%s", zone->name);
/* MMOP_ONLINE_KERNEL */
zone_shift = zone_can_shift(start_pfn, nr_pages, ZONE_NORMAL);
zone_can_shift(start_pfn, nr_pages, ZONE_NORMAL, &zone_shift);
if (zone_shift) {
strcat(buf, " ");
strcat(buf, (zone + zone_shift)->name);
}
/* MMOP_ONLINE_MOVABLE */
zone_shift = zone_can_shift(start_pfn, nr_pages, ZONE_MOVABLE);
zone_can_shift(start_pfn, nr_pages, ZONE_MOVABLE, &zone_shift);
if (zone_shift) {
strcat(buf, " ");
strcat(buf, (zone + zone_shift)->name);

View File

@@ -3115,6 +3115,8 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
if (state->fb)
drm_framebuffer_reference(state->fb);
state->fence = NULL;
}
EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);

View File

@@ -1462,6 +1462,13 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev,
return NULL;
mode->type |= DRM_MODE_TYPE_USERDEF;
/* fix up 1368x768: GFT/CVT can't express 1366 width due to alignment */
if (cmd->xres == 1366 && mode->hdisplay == 1368) {
mode->hdisplay = 1366;
mode->hsync_start--;
mode->hsync_end--;
drm_mode_set_name(mode);
}
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
return mode;
}

View File

@@ -143,8 +143,18 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
}
if (dev->mode_config.delayed_event) {
/*
* FIXME:
*
* Use short (1s) delay to handle the initial delayed event.
* This delay should not be needed, but Optimus/nouveau will
* fail in a mysterious way if the delayed event is handled as
* soon as possible like it is done in
* drm_helper_probe_single_connector_modes() in case the poll
* was enabled before.
*/
poll = true;
delay = 0;
delay = HZ;
}
if (poll)

View File

@@ -2372,7 +2372,7 @@ static int intel_runtime_suspend(struct device *kdev)
assert_forcewakes_inactive(dev_priv);
if (!IS_VALLEYVIEW(dev_priv) || !IS_CHERRYVIEW(dev_priv))
if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv))
intel_hpd_poll_init(dev_priv);
DRM_DEBUG_KMS("Device suspended\n");

View File

@@ -194,6 +194,7 @@ found:
}
/* Unbinding will emit any required flushes */
ret = 0;
while (!list_empty(&eviction_list)) {
vma = list_first_entry(&eviction_list,
struct i915_vma,

View File

@@ -499,6 +499,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
struct drm_i915_private *dev_priv = to_i915(crt->base.base.dev);
struct edid *edid;
struct i2c_adapter *i2c;
bool ret = false;
BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);
@@ -515,17 +516,17 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
*/
if (!is_digital) {
DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
return true;
ret = true;
} else {
DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
}
DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
} else {
DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [no valid EDID found]\n");
}
kfree(edid);
return false;
return ret;
}
static enum drm_connector_status

View File

@@ -2587,8 +2587,9 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
* We only keep the x/y offsets, so push all of the
* gtt offset into the x/y offsets.
*/
_intel_adjust_tile_offset(&x, &y, tile_size,
tile_width, tile_height, pitch_tiles,
_intel_adjust_tile_offset(&x, &y,
tile_width, tile_height,
tile_size, pitch_tiles,
gtt_offset_rotated * tile_size, 0);
gtt_offset_rotated += rot_info->plane[i].width * rot_info->plane[i].height;
@@ -2975,6 +2976,9 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
unsigned int rotation = plane_state->base.rotation;
int ret;
if (!plane_state->base.visible)
return 0;
/* Rotate src coordinates to match rotated GTT view */
if (intel_rotation_90_or_270(rotation))
drm_rect_rotate(&plane_state->base.src,
@@ -6865,6 +6869,12 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc)
}
state = drm_atomic_state_alloc(crtc->dev);
if (!state) {
DRM_DEBUG_KMS("failed to disable [CRTC:%d:%s], out of memory",
crtc->base.id, crtc->name);
return;
}
state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
/* Everything's already locked, -EDEADLK can't happen. */

View File

@@ -745,6 +745,9 @@ void intel_fbdev_initial_config_async(struct drm_device *dev)
{
struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
if (!ifbdev)
return;
ifbdev->cookie = async_schedule(intel_fbdev_initial_config, ifbdev);
}

View File

@@ -858,8 +858,7 @@ static inline int gen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine,
* this batch updates GEN8_L3SQCREG4 with default value we need to
* set this bit here to retain the WA during flush.
*/
if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_E0) ||
IS_KBL_REVID(dev_priv, 0, KBL_REVID_E0))
if (IS_SKL_REVID(dev_priv, 0, SKL_REVID_E0))
l3sqc4_flush |= GEN8_LQSC_RO_PERF_DIS;
wa_ctx_emit(batch, index, (MI_STORE_REGISTER_MEM_GEN8 |

View File

@@ -1153,14 +1153,6 @@ static int kbl_init_workarounds(struct intel_engine_cs *engine)
WA_SET_BIT_MASKED(HDC_CHICKEN0,
HDC_FENCE_DEST_SLM_DISABLE);
/* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes
* involving this register should also be added to WA batch as required.
*/
if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_E0))
/* WaDisableLSQCROPERFforOCL:kbl */
I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) |
GEN8_LQSC_RO_PERF_DIS);
/* WaToEnableHwFixForPushConstHWBug:kbl */
if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,

View File

@@ -366,11 +366,10 @@ static void
radeon_pci_shutdown(struct pci_dev *pdev)
{
/* if we are running in a VM, make sure the device
* torn down properly on reboot/shutdown.
* unfortunately we can't detect certain
* hypervisors so just do this all the time.
* torn down properly on reboot/shutdown
*/
radeon_pci_remove(pdev);
if (radeon_device_is_virtual())
radeon_pci_remove(pdev);
}
static int radeon_pmops_suspend(struct device *dev)

View File

@@ -832,7 +832,7 @@ static void vc4_crtc_destroy_state(struct drm_crtc *crtc,
}
__drm_atomic_helper_crtc_destroy_state(state);
drm_atomic_helper_crtc_destroy_state(crtc, state);
}
static const struct drm_crtc_funcs vc4_crtc_funcs = {

View File

@@ -594,12 +594,14 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
args->shader_rec_count);
struct vc4_bo *bo;
if (uniforms_offset < shader_rec_offset ||
if (shader_rec_offset < args->bin_cl_size ||
uniforms_offset < shader_rec_offset ||
exec_size < uniforms_offset ||
args->shader_rec_count >= (UINT_MAX /
sizeof(struct vc4_shader_state)) ||
temp_size < exec_size) {
DRM_ERROR("overflow in exec arguments\n");
ret = -EINVAL;
goto fail;
}

View File

@@ -461,7 +461,7 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
}
ret = vc4_full_res_bounds_check(exec, *obj, surf);
if (!ret)
if (ret)
return ret;
return 0;

View File

@@ -2768,7 +2768,8 @@ static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
if (!src_addr || !src_addr->sa_family) {
src_addr = (struct sockaddr *) &id->route.addr.src_addr;
src_addr->sa_family = dst_addr->sa_family;
if (dst_addr->sa_family == AF_INET6) {
if (IS_ENABLED(CONFIG_IPV6) &&
dst_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *src_addr6 = (struct sockaddr_in6 *) src_addr;
struct sockaddr_in6 *dst_addr6 = (struct sockaddr_in6 *) dst_addr;
src_addr6->sin6_scope_id = dst_addr6->sin6_scope_id;

View File

@@ -134,6 +134,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND));
if (access & IB_ACCESS_ON_DEMAND) {
put_pid(umem->pid);
ret = ib_umem_odp_get(context, umem);
if (ret) {
kfree(umem);
@@ -149,6 +150,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
page_list = (struct page **) __get_free_page(GFP_KERNEL);
if (!page_list) {
put_pid(umem->pid);
kfree(umem);
return ERR_PTR(-ENOMEM);
}

View File

@@ -848,9 +848,17 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
}
}
rdev->free_workq = create_singlethread_workqueue("iw_cxgb4_free");
if (!rdev->free_workq) {
err = -ENOMEM;
goto err_free_status_page;
}
rdev->status_page->db_off = 0;
return 0;
err_free_status_page:
free_page((unsigned long)rdev->status_page);
destroy_ocqp_pool:
c4iw_ocqp_pool_destroy(rdev);
destroy_rqtpool:
@@ -864,6 +872,7 @@ destroy_resource:
static void c4iw_rdev_close(struct c4iw_rdev *rdev)
{
destroy_workqueue(rdev->free_workq);
kfree(rdev->wr_log);
free_page((unsigned long)rdev->status_page);
c4iw_pblpool_destroy(rdev);

View File

@@ -45,6 +45,7 @@
#include <linux/kref.h>
#include <linux/timer.h>
#include <linux/io.h>
#include <linux/workqueue.h>
#include <asm/byteorder.h>
@@ -107,6 +108,7 @@ struct c4iw_dev_ucontext {
struct list_head qpids;
struct list_head cqids;
struct mutex lock;
struct kref kref;
};
enum c4iw_rdev_flags {
@@ -183,6 +185,7 @@ struct c4iw_rdev {
atomic_t wr_log_idx;
struct wr_log_entry *wr_log;
int wr_log_size;
struct workqueue_struct *free_workq;
};
static inline int c4iw_fatal_error(struct c4iw_rdev *rdev)
@@ -482,6 +485,8 @@ struct c4iw_qp {
int sq_sig_all;
struct completion rq_drained;
struct completion sq_drained;
struct work_struct free_work;
struct c4iw_ucontext *ucontext;
};
static inline struct c4iw_qp *to_c4iw_qp(struct ib_qp *ibqp)
@@ -495,6 +500,7 @@ struct c4iw_ucontext {
u32 key;
spinlock_t mmap_lock;
struct list_head mmaps;
struct kref kref;
};
static inline struct c4iw_ucontext *to_c4iw_ucontext(struct ib_ucontext *c)
@@ -502,6 +508,18 @@ static inline struct c4iw_ucontext *to_c4iw_ucontext(struct ib_ucontext *c)
return container_of(c, struct c4iw_ucontext, ibucontext);
}
void _c4iw_free_ucontext(struct kref *kref);
static inline void c4iw_put_ucontext(struct c4iw_ucontext *ucontext)
{
kref_put(&ucontext->kref, _c4iw_free_ucontext);
}
static inline void c4iw_get_ucontext(struct c4iw_ucontext *ucontext)
{
kref_get(&ucontext->kref);
}
struct c4iw_mm_entry {
struct list_head entry;
u64 addr;

View File

@@ -91,17 +91,28 @@ static int c4iw_process_mad(struct ib_device *ibdev, int mad_flags,
return -ENOSYS;
}
static int c4iw_dealloc_ucontext(struct ib_ucontext *context)
void _c4iw_free_ucontext(struct kref *kref)
{
struct c4iw_dev *rhp = to_c4iw_dev(context->device);
struct c4iw_ucontext *ucontext = to_c4iw_ucontext(context);
struct c4iw_ucontext *ucontext;
struct c4iw_dev *rhp;
struct c4iw_mm_entry *mm, *tmp;
PDBG("%s context %p\n", __func__, context);
ucontext = container_of(kref, struct c4iw_ucontext, kref);
rhp = to_c4iw_dev(ucontext->ibucontext.device);
PDBG("%s ucontext %p\n", __func__, ucontext);
list_for_each_entry_safe(mm, tmp, &ucontext->mmaps, entry)
kfree(mm);
c4iw_release_dev_ucontext(&rhp->rdev, &ucontext->uctx);
kfree(ucontext);
}
static int c4iw_dealloc_ucontext(struct ib_ucontext *context)
{
struct c4iw_ucontext *ucontext = to_c4iw_ucontext(context);
PDBG("%s context %p\n", __func__, context);
c4iw_put_ucontext(ucontext);
return 0;
}
@@ -125,6 +136,7 @@ static struct ib_ucontext *c4iw_alloc_ucontext(struct ib_device *ibdev,
c4iw_init_dev_ucontext(&rhp->rdev, &context->uctx);
INIT_LIST_HEAD(&context->mmaps);
spin_lock_init(&context->mmap_lock);
kref_init(&context->kref);
if (udata->outlen < sizeof(uresp) - sizeof(uresp.reserved)) {
if (!warned++)

View File

@@ -714,13 +714,32 @@ static int build_inv_stag(union t4_wr *wqe, struct ib_send_wr *wr, u8 *len16)
return 0;
}
static void _free_qp(struct kref *kref)
static void free_qp_work(struct work_struct *work)
{
struct c4iw_ucontext *ucontext;
struct c4iw_qp *qhp;
struct c4iw_dev *rhp;
qhp = container_of(work, struct c4iw_qp, free_work);
ucontext = qhp->ucontext;
rhp = qhp->rhp;
PDBG("%s qhp %p ucontext %p\n", __func__, qhp, ucontext);
destroy_qp(&rhp->rdev, &qhp->wq,
ucontext ? &ucontext->uctx : &rhp->rdev.uctx);
if (ucontext)
c4iw_put_ucontext(ucontext);
kfree(qhp);
}
static void queue_qp_free(struct kref *kref)
{
struct c4iw_qp *qhp;
qhp = container_of(kref, struct c4iw_qp, kref);
PDBG("%s qhp %p\n", __func__, qhp);
kfree(qhp);
queue_work(qhp->rhp->rdev.free_workq, &qhp->free_work);
}
void c4iw_qp_add_ref(struct ib_qp *qp)
@@ -732,7 +751,7 @@ void c4iw_qp_add_ref(struct ib_qp *qp)
void c4iw_qp_rem_ref(struct ib_qp *qp)
{
PDBG("%s ib_qp %p\n", __func__, qp);
kref_put(&to_c4iw_qp(qp)->kref, _free_qp);
kref_put(&to_c4iw_qp(qp)->kref, queue_qp_free);
}
static void add_to_fc_list(struct list_head *head, struct list_head *entry)
@@ -1642,7 +1661,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
struct c4iw_dev *rhp;
struct c4iw_qp *qhp;
struct c4iw_qp_attributes attrs;
struct c4iw_ucontext *ucontext;
qhp = to_c4iw_qp(ib_qp);
rhp = qhp->rhp;
@@ -1662,11 +1680,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
spin_unlock_irq(&rhp->lock);
free_ird(rhp, qhp->attr.max_ird);
ucontext = ib_qp->uobject ?
to_c4iw_ucontext(ib_qp->uobject->context) : NULL;
destroy_qp(&rhp->rdev, &qhp->wq,
ucontext ? &ucontext->uctx : &rhp->rdev.uctx);
c4iw_qp_rem_ref(ib_qp);
PDBG("%s ib_qp %p qpid 0x%0x\n", __func__, ib_qp, qhp->wq.sq.qid);
@@ -1767,6 +1780,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
mutex_init(&qhp->mutex);
init_waitqueue_head(&qhp->wait);
kref_init(&qhp->kref);
INIT_WORK(&qhp->free_work, free_qp_work);
ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
if (ret)
@@ -1853,6 +1867,9 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
ma_sync_key_mm->len = PAGE_SIZE;
insert_mmap(ucontext, ma_sync_key_mm);
}
c4iw_get_ucontext(ucontext);
qhp->ucontext = ucontext;
}
qhp->ibqp.qp_num = qhp->wq.sq.qid;
init_timer(&(qhp->timer));

View File

@@ -554,7 +554,7 @@ struct rxe_dev *rxe_net_add(struct net_device *ndev)
}
spin_lock_bh(&dev_list_lock);
list_add_tail(&rxe_dev_list, &rxe->list);
list_add_tail(&rxe->list, &rxe_dev_list);
spin_unlock_bh(&dev_list_lock);
return rxe;
}

View File

@@ -813,8 +813,7 @@ void rxe_qp_destroy(struct rxe_qp *qp)
del_timer_sync(&qp->rnr_nak_timer);
rxe_cleanup_task(&qp->req.task);
if (qp_type(qp) == IB_QPT_RC)
rxe_cleanup_task(&qp->comp.task);
rxe_cleanup_task(&qp->comp.task);
/* flush out any receive wr's or pending requests */
__rxe_do_task(&qp->req.task);

View File

@@ -651,13 +651,6 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
SHOST_DIX_GUARD_CRC);
}
/*
* Limit the sg_tablesize and max_sectors based on the device
* max fastreg page list length.
*/
shost->sg_tablesize = min_t(unsigned short, shost->sg_tablesize,
ib_conn->device->ib_device->attrs.max_fast_reg_page_list_len);
if (iscsi_host_add(shost,
ib_conn->device->ib_device->dma_device)) {
mutex_unlock(&iser_conn->state_mutex);

View File

@@ -366,6 +366,7 @@ static struct srp_fr_pool *srp_create_fr_pool(struct ib_device *device,
struct srp_fr_desc *d;
struct ib_mr *mr;
int i, ret = -EINVAL;
enum ib_mr_type mr_type;
if (pool_size <= 0)
goto err;
@@ -379,9 +380,13 @@ static struct srp_fr_pool *srp_create_fr_pool(struct ib_device *device,
spin_lock_init(&pool->lock);
INIT_LIST_HEAD(&pool->free_list);
if (device->attrs.device_cap_flags & IB_DEVICE_SG_GAPS_REG)
mr_type = IB_MR_TYPE_SG_GAPS;
else
mr_type = IB_MR_TYPE_MEM_REG;
for (i = 0, d = &pool->desc[0]; i < pool->size; i++, d++) {
mr = ib_alloc_mr(pd, IB_MR_TYPE_MEM_REG,
max_page_list_len);
mr = ib_alloc_mr(pd, mr_type, max_page_list_len);
if (IS_ERR(mr)) {
ret = PTR_ERR(mr);
goto destroy_pool;
@@ -3678,6 +3683,12 @@ static int __init srp_init_module(void)
indirect_sg_entries = cmd_sg_entries;
}
if (indirect_sg_entries > SG_MAX_SEGMENTS) {
pr_warn("Clamping indirect_sg_entries to %u\n",
SG_MAX_SEGMENTS);
indirect_sg_entries = SG_MAX_SEGMENTS;
}
srp_remove_wq = create_workqueue("srp_remove");
if (!srp_remove_wq) {
ret = -ENOMEM;

View File

@@ -11297,7 +11297,8 @@ static void mixer_notify_update(PLCI *plci, byte others)
((CAPI_MSG *) msg)->header.ncci = 0;
((CAPI_MSG *) msg)->info.facility_req.Selector = SELECTOR_LINE_INTERCONNECT;
((CAPI_MSG *) msg)->info.facility_req.structs[0] = 3;
PUT_WORD(&(((CAPI_MSG *) msg)->info.facility_req.structs[1]), LI_REQ_SILENT_UPDATE);
((CAPI_MSG *) msg)->info.facility_req.structs[1] = LI_REQ_SILENT_UPDATE & 0xff;
((CAPI_MSG *) msg)->info.facility_req.structs[2] = LI_REQ_SILENT_UPDATE >> 8;
((CAPI_MSG *) msg)->info.facility_req.structs[3] = 0;
w = api_put(notify_plci->appl, (CAPI_MSG *) msg);
if (w != _QUEUE_FULL)

View File

@@ -655,6 +655,7 @@ config VIDEO_S5K6A3
config VIDEO_S5K4ECGX
tristate "Samsung S5K4ECGX sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
select CRC32
---help---
This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
camera sensor with an embedded SoC image signal processor.

View File

@@ -288,8 +288,12 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd)
tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode);
tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input);
/* Svideo should enable YCrCb output and disable GPCL output
* For Composite and TV, it should be the reverse
/*
* Setup the FID/GLCO/VLK/HVLK and INTREQ/GPCL/VBLK output signals. For
* S-Video we output the vertical lock (VLK) signal on FID/GLCO/VLK/HVLK
* and set INTREQ/GPCL/VBLK to logic 0. For composite we output the
* field indicator (FID) signal on FID/GLCO/VLK/HVLK and set
* INTREQ/GPCL/VBLK to logic 1.
*/
val = tvp5150_read(sd, TVP5150_MISC_CTL);
if (val < 0) {
@@ -298,9 +302,9 @@ static inline void tvp5150_selmux(struct v4l2_subdev *sd)
}
if (decoder->input == TVP5150_SVIDEO)
val = (val & ~0x40) | 0x10;
val = (val & ~TVP5150_MISC_CTL_GPCL) | TVP5150_MISC_CTL_HVLK;
else
val = (val & ~0x10) | 0x40;
val = (val & ~TVP5150_MISC_CTL_HVLK) | TVP5150_MISC_CTL_GPCL;
tvp5150_write(sd, TVP5150_MISC_CTL, val);
};
@@ -452,7 +456,12 @@ static const struct i2c_reg_value tvp5150_init_enable[] = {
},{ /* Automatic offset and AGC enabled */
TVP5150_ANAL_CHL_CTL, 0x15
},{ /* Activate YCrCb output 0x9 or 0xd ? */
TVP5150_MISC_CTL, 0x6f
TVP5150_MISC_CTL, TVP5150_MISC_CTL_GPCL |
TVP5150_MISC_CTL_INTREQ_OE |
TVP5150_MISC_CTL_YCBCR_OE |
TVP5150_MISC_CTL_SYNC_OE |
TVP5150_MISC_CTL_VBLANK |
TVP5150_MISC_CTL_CLOCK_OE,
},{ /* Activates video std autodetection for all standards */
TVP5150_AUTOSW_MSK, 0x0
},{ /* Default format: 0x47. For 4:2:2: 0x40 */
@@ -858,8 +867,6 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd,
f = &format->format;
tvp5150_reset(sd, 0);
f->width = decoder->rect.width;
f->height = decoder->rect.height / 2;
@@ -1048,21 +1055,27 @@ static const struct media_entity_operations tvp5150_sd_media_ops = {
static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable)
{
struct tvp5150 *decoder = to_tvp5150(sd);
/* Output format: 8-bit ITU-R BT.656 with embedded syncs */
int val = 0x09;
int val;
/* Output format: 8-bit 4:2:2 YUV with discrete sync */
if (decoder->mbus_type == V4L2_MBUS_PARALLEL)
val = 0x0d;
/* Enable or disable the video output signals. */
val = tvp5150_read(sd, TVP5150_MISC_CTL);
if (val < 0)
return val;
/* Initializes TVP5150 to its default values */
/* # set PCLK (27MHz) */
tvp5150_write(sd, TVP5150_CONF_SHARED_PIN, 0x00);
val &= ~(TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE |
TVP5150_MISC_CTL_CLOCK_OE);
if (enable)
tvp5150_write(sd, TVP5150_MISC_CTL, val);
else
tvp5150_write(sd, TVP5150_MISC_CTL, 0x00);
if (enable) {
/*
* Enable the YCbCr and clock outputs. In discrete sync mode
* (non-BT.656) additionally enable the the sync outputs.
*/
val |= TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_CLOCK_OE;
if (decoder->mbus_type == V4L2_MBUS_PARALLEL)
val |= TVP5150_MISC_CTL_SYNC_OE;
}
tvp5150_write(sd, TVP5150_MISC_CTL, val);
return 0;
}
@@ -1521,7 +1534,6 @@ static int tvp5150_probe(struct i2c_client *c,
res = core->hdl.error;
goto err;
}
v4l2_ctrl_handler_setup(&core->hdl);
/* Default is no cropping */
core->rect.top = 0;
@@ -1532,6 +1544,8 @@ static int tvp5150_probe(struct i2c_client *c,
core->rect.left = 0;
core->rect.width = TVP5150_H_MAX;
tvp5150_reset(sd, 0); /* Calls v4l2_ctrl_handler_setup() */
res = v4l2_async_register_subdev(sd);
if (res < 0)
goto err;

View File

@@ -9,6 +9,15 @@
#define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */
#define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */
#define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */
#define TVP5150_MISC_CTL_VBLK_GPCL BIT(7)
#define TVP5150_MISC_CTL_GPCL BIT(6)
#define TVP5150_MISC_CTL_INTREQ_OE BIT(5)
#define TVP5150_MISC_CTL_HVLK BIT(4)
#define TVP5150_MISC_CTL_YCBCR_OE BIT(3)
#define TVP5150_MISC_CTL_SYNC_OE BIT(2)
#define TVP5150_MISC_CTL_VBLANK BIT(1)
#define TVP5150_MISC_CTL_CLOCK_OE BIT(0)
#define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */
/* Reserved 05h */

View File

@@ -97,14 +97,13 @@ struct pctv452e_state {
u8 c; /* transaction counter, wraps around... */
u8 initialized; /* set to 1 if 0x15 has been sent */
u16 last_rc_key;
unsigned char data[80];
};
static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
unsigned int write_len, unsigned int read_len)
{
struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
u8 *buf;
u8 id;
unsigned int rlen;
int ret;
@@ -114,36 +113,39 @@ static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
return -EIO;
}
mutex_lock(&state->ca_mutex);
buf = kmalloc(64, GFP_KERNEL);
if (!buf)
return -ENOMEM;
id = state->c++;
state->data[0] = SYNC_BYTE_OUT;
state->data[1] = id;
state->data[2] = cmd;
state->data[3] = write_len;
buf[0] = SYNC_BYTE_OUT;
buf[1] = id;
buf[2] = cmd;
buf[3] = write_len;
memcpy(state->data + 4, data, write_len);
memcpy(buf + 4, data, write_len);
rlen = (read_len > 0) ? 64 : 0;
ret = dvb_usb_generic_rw(d, state->data, 4 + write_len,
state->data, rlen, /* delay_ms */ 0);
ret = dvb_usb_generic_rw(d, buf, 4 + write_len,
buf, rlen, /* delay_ms */ 0);
if (0 != ret)
goto failed;
ret = -EIO;
if (SYNC_BYTE_IN != state->data[0] || id != state->data[1])
if (SYNC_BYTE_IN != buf[0] || id != buf[1])
goto failed;
memcpy(data, state->data + 4, read_len);
memcpy(data, buf + 4, read_len);
mutex_unlock(&state->ca_mutex);
kfree(buf);
return 0;
failed:
err("CI error %d; %02X %02X %02X -> %*ph.",
ret, SYNC_BYTE_OUT, id, cmd, 3, state->data);
ret, SYNC_BYTE_OUT, id, cmd, 3, buf);
mutex_unlock(&state->ca_mutex);
kfree(buf);
return ret;
}
@@ -410,53 +412,57 @@ static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr,
u8 *rcv_buf, u8 rcv_len)
{
struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
u8 *buf;
u8 id;
int ret;
mutex_lock(&state->ca_mutex);
buf = kmalloc(64, GFP_KERNEL);
if (!buf)
return -ENOMEM;
id = state->c++;
ret = -EINVAL;
if (snd_len > 64 - 7 || rcv_len > 64 - 7)
goto failed;
state->data[0] = SYNC_BYTE_OUT;
state->data[1] = id;
state->data[2] = PCTV_CMD_I2C;
state->data[3] = snd_len + 3;
state->data[4] = addr << 1;
state->data[5] = snd_len;
state->data[6] = rcv_len;
buf[0] = SYNC_BYTE_OUT;
buf[1] = id;
buf[2] = PCTV_CMD_I2C;
buf[3] = snd_len + 3;
buf[4] = addr << 1;
buf[5] = snd_len;
buf[6] = rcv_len;
memcpy(state->data + 7, snd_buf, snd_len);
memcpy(buf + 7, snd_buf, snd_len);
ret = dvb_usb_generic_rw(d, state->data, 7 + snd_len,
state->data, /* rcv_len */ 64,
ret = dvb_usb_generic_rw(d, buf, 7 + snd_len,
buf, /* rcv_len */ 64,
/* delay_ms */ 0);
if (ret < 0)
goto failed;
/* TT USB protocol error. */
ret = -EIO;
if (SYNC_BYTE_IN != state->data[0] || id != state->data[1])
if (SYNC_BYTE_IN != buf[0] || id != buf[1])
goto failed;
/* I2C device didn't respond as expected. */
ret = -EREMOTEIO;
if (state->data[5] < snd_len || state->data[6] < rcv_len)
if (buf[5] < snd_len || buf[6] < rcv_len)
goto failed;
memcpy(rcv_buf, state->data + 7, rcv_len);
mutex_unlock(&state->ca_mutex);
memcpy(rcv_buf, buf + 7, rcv_len);
kfree(buf);
return rcv_len;
failed:
err("I2C error %d; %02X %02X %02X %02X %02X -> %*ph",
ret, SYNC_BYTE_OUT, id, addr << 1, snd_len, rcv_len,
7, state->data);
7, buf);
mutex_unlock(&state->ca_mutex);
kfree(buf);
return ret;
}
@@ -505,7 +511,7 @@ static u32 pctv452e_i2c_func(struct i2c_adapter *adapter)
static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i)
{
struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
u8 *rx;
u8 *b0, *rx;
int ret;
info("%s: %d\n", __func__, i);
@@ -516,11 +522,12 @@ static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i)
if (state->initialized)
return 0;
rx = kmalloc(PCTV_ANSWER_LEN, GFP_KERNEL);
if (!rx)
b0 = kmalloc(5 + PCTV_ANSWER_LEN, GFP_KERNEL);
if (!b0)
return -ENOMEM;
mutex_lock(&state->ca_mutex);
rx = b0 + 5;
/* hmm where shoud this should go? */
ret = usb_set_interface(d->udev, 0, ISOC_INTERFACE_ALTERNATIVE);
if (ret != 0)
@@ -528,66 +535,70 @@ static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i)
__func__, ret);
/* this is a one-time initialization, dont know where to put */
state->data[0] = 0xaa;
state->data[1] = state->c++;
state->data[2] = PCTV_CMD_RESET;
state->data[3] = 1;
state->data[4] = 0;
b0[0] = 0xaa;
b0[1] = state->c++;
b0[2] = PCTV_CMD_RESET;
b0[3] = 1;
b0[4] = 0;
/* reset board */
ret = dvb_usb_generic_rw(d, state->data, 5, rx, PCTV_ANSWER_LEN, 0);
ret = dvb_usb_generic_rw(d, b0, 5, rx, PCTV_ANSWER_LEN, 0);
if (ret)
goto ret;
state->data[1] = state->c++;
state->data[4] = 1;
b0[1] = state->c++;
b0[4] = 1;
/* reset board (again?) */
ret = dvb_usb_generic_rw(d, state->data, 5, rx, PCTV_ANSWER_LEN, 0);
ret = dvb_usb_generic_rw(d, b0, 5, rx, PCTV_ANSWER_LEN, 0);
if (ret)
goto ret;
state->initialized = 1;
ret:
mutex_unlock(&state->ca_mutex);
kfree(rx);
kfree(b0);
return ret;
}
static int pctv452e_rc_query(struct dvb_usb_device *d)
{
struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
u8 *b, *rx;
int ret, i;
u8 id;
mutex_lock(&state->ca_mutex);
b = kmalloc(CMD_BUFFER_SIZE + PCTV_ANSWER_LEN, GFP_KERNEL);
if (!b)
return -ENOMEM;
rx = b + CMD_BUFFER_SIZE;
id = state->c++;
/* prepare command header */
state->data[0] = SYNC_BYTE_OUT;
state->data[1] = id;
state->data[2] = PCTV_CMD_IR;
state->data[3] = 0;
b[0] = SYNC_BYTE_OUT;
b[1] = id;
b[2] = PCTV_CMD_IR;
b[3] = 0;
/* send ir request */
ret = dvb_usb_generic_rw(d, state->data, 4,
state->data, PCTV_ANSWER_LEN, 0);
ret = dvb_usb_generic_rw(d, b, 4, rx, PCTV_ANSWER_LEN, 0);
if (ret != 0)
goto ret;
if (debug > 3) {
info("%s: read: %2d: %*ph: ", __func__, ret, 3, state->data);
for (i = 0; (i < state->data[3]) && ((i + 3) < PCTV_ANSWER_LEN); i++)
info(" %02x", state->data[i + 3]);
info("%s: read: %2d: %*ph: ", __func__, ret, 3, rx);
for (i = 0; (i < rx[3]) && ((i+3) < PCTV_ANSWER_LEN); i++)
info(" %02x", rx[i+3]);
info("\n");
}
if ((state->data[3] == 9) && (state->data[12] & 0x01)) {
if ((rx[3] == 9) && (rx[12] & 0x01)) {
/* got a "press" event */
state->last_rc_key = RC_SCANCODE_RC5(state->data[7], state->data[6]);
state->last_rc_key = RC_SCANCODE_RC5(rx[7], rx[6]);
if (debug > 2)
info("%s: cmd=0x%02x sys=0x%02x\n",
__func__, state->data[6], state->data[7]);
__func__, rx[6], rx[7]);
rc_keydown(d->rc_dev, RC_TYPE_RC5, state->last_rc_key, 0);
} else if (state->last_rc_key) {
@@ -595,7 +606,7 @@ static int pctv452e_rc_query(struct dvb_usb_device *d)
state->last_rc_key = 0;
}
ret:
mutex_unlock(&state->ca_mutex);
kfree(b);
return ret;
}

View File

@@ -161,6 +161,7 @@ static int c_can_pci_probe(struct pci_dev *pdev,
dev->irq = pdev->irq;
priv->base = addr;
priv->device = &pdev->dev;
if (!c_can_pci_data->freq) {
dev_err(&pdev->dev, "no clock frequency defined\n");

View File

@@ -948,7 +948,12 @@ static int ti_hecc_probe(struct platform_device *pdev)
netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
HECC_DEF_NAPI_WEIGHT);
clk_enable(priv->clk);
err = clk_prepare_enable(priv->clk);
if (err) {
dev_err(&pdev->dev, "clk_prepare_enable() failed\n");
goto probe_exit_clk;
}
err = register_candev(ndev);
if (err) {
dev_err(&pdev->dev, "register_candev() failed\n");
@@ -981,7 +986,7 @@ static int ti_hecc_remove(struct platform_device *pdev)
struct ti_hecc_priv *priv = netdev_priv(ndev);
unregister_candev(ndev);
clk_disable(priv->clk);
clk_disable_unprepare(priv->clk);
clk_put(priv->clk);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
iounmap(priv->base);
@@ -1006,7 +1011,7 @@ static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
priv->can.state = CAN_STATE_SLEEPING;
clk_disable(priv->clk);
clk_disable_unprepare(priv->clk);
return 0;
}
@@ -1015,8 +1020,11 @@ static int ti_hecc_resume(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct ti_hecc_priv *priv = netdev_priv(dev);
int err;
clk_enable(priv->clk);
err = clk_prepare_enable(priv->clk);
if (err)
return err;
hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
priv->can.state = CAN_STATE_ERROR_ACTIVE;

View File

@@ -710,11 +710,8 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs;
unsigned int pkts_compl = 0, bytes_compl = 0;
struct bcm_sysport_cb *cb;
struct netdev_queue *txq;
u32 hw_ind;
txq = netdev_get_tx_queue(ndev, ring->index);
/* Compute how many descriptors have been processed since last call */
hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index));
c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK;
@@ -745,9 +742,6 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
ring->c_index = c_index;
if (netif_tx_queue_stopped(txq) && pkts_compl)
netif_tx_wake_queue(txq);
netif_dbg(priv, tx_done, ndev,
"ring=%d c_index=%d pkts_compl=%d, bytes_compl=%d\n",
ring->index, ring->c_index, pkts_compl, bytes_compl);
@@ -759,16 +753,33 @@ static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
static unsigned int bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
struct bcm_sysport_tx_ring *ring)
{
struct netdev_queue *txq;
unsigned int released;
unsigned long flags;
txq = netdev_get_tx_queue(priv->netdev, ring->index);
spin_lock_irqsave(&ring->lock, flags);
released = __bcm_sysport_tx_reclaim(priv, ring);
if (released)
netif_tx_wake_queue(txq);
spin_unlock_irqrestore(&ring->lock, flags);
return released;
}
/* Locked version of the per-ring TX reclaim, but does not wake the queue */
static void bcm_sysport_tx_clean(struct bcm_sysport_priv *priv,
struct bcm_sysport_tx_ring *ring)
{
unsigned long flags;
spin_lock_irqsave(&ring->lock, flags);
__bcm_sysport_tx_reclaim(priv, ring);
spin_unlock_irqrestore(&ring->lock, flags);
}
static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget)
{
struct bcm_sysport_tx_ring *ring =
@@ -1253,7 +1264,7 @@ static void bcm_sysport_fini_tx_ring(struct bcm_sysport_priv *priv,
napi_disable(&ring->napi);
netif_napi_del(&ring->napi);
bcm_sysport_tx_reclaim(priv, ring);
bcm_sysport_tx_clean(priv, ring);
kfree(ring->cbs);
ring->cbs = NULL;

View File

@@ -1740,8 +1740,11 @@ int mlx4_en_start_port(struct net_device *dev)
/* Process all completions if exist to prevent
* the queues freezing if they are full
*/
for (i = 0; i < priv->rx_ring_num; i++)
for (i = 0; i < priv->rx_ring_num; i++) {
local_bh_disable();
napi_schedule(&priv->rx_cq[i]->napi);
local_bh_enable();
}
netif_tx_start_all_queues(dev);
netif_device_attach(dev);

View File

@@ -193,6 +193,9 @@ static inline bool mlx5e_rx_cache_put(struct mlx5e_rq *rq,
return false;
}
if (unlikely(page_is_pfmemalloc(dma_info->page)))
return false;
cache->page_cache[cache->tail] = *dma_info;
cache->tail = tail_next;
return true;

View File

@@ -211,21 +211,21 @@ MLXSW_ITEM32(pci, eqe, owner, 0x0C, 0, 1);
/* pci_eqe_cmd_token
* Command completion event - token
*/
MLXSW_ITEM32(pci, eqe, cmd_token, 0x08, 16, 16);
MLXSW_ITEM32(pci, eqe, cmd_token, 0x00, 16, 16);
/* pci_eqe_cmd_status
* Command completion event - status
*/
MLXSW_ITEM32(pci, eqe, cmd_status, 0x08, 0, 8);
MLXSW_ITEM32(pci, eqe, cmd_status, 0x00, 0, 8);
/* pci_eqe_cmd_out_param_h
* Command completion event - output parameter - higher part
*/
MLXSW_ITEM32(pci, eqe, cmd_out_param_h, 0x0C, 0, 32);
MLXSW_ITEM32(pci, eqe, cmd_out_param_h, 0x04, 0, 32);
/* pci_eqe_cmd_out_param_l
* Command completion event - output parameter - lower part
*/
MLXSW_ITEM32(pci, eqe, cmd_out_param_l, 0x10, 0, 32);
MLXSW_ITEM32(pci, eqe, cmd_out_param_l, 0x08, 0, 32);
#endif

View File

@@ -684,6 +684,7 @@ static netdev_tx_t mlxsw_sp_port_xmit(struct sk_buff *skb,
dev_kfree_skb_any(skb_orig);
return NETDEV_TX_OK;
}
dev_consume_skb_any(skb_orig);
}
if (eth_skb_pad(skb)) {

View File

@@ -314,6 +314,7 @@ static netdev_tx_t mlxsw_sx_port_xmit(struct sk_buff *skb,
dev_kfree_skb_any(skb_orig);
return NETDEV_TX_OK;
}
dev_consume_skb_any(skb_orig);
}
mlxsw_sx_txhdr_construct(skb, &tx_info);
/* TX header is consumed by HW on the way so we shouldn't count its

View File

@@ -1508,6 +1508,19 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
buffer = PTR_ALIGN(priv->tx_align[q], DPTR_ALIGN) +
entry / NUM_TX_DESC * DPTR_ALIGN;
len = PTR_ALIGN(skb->data, DPTR_ALIGN) - skb->data;
/* Zero length DMA descriptors are problematic as they seem to
* terminate DMA transfers. Avoid them by simply using a length of
* DPTR_ALIGN (4) when skb data is aligned to DPTR_ALIGN.
*
* As skb is guaranteed to have at least ETH_ZLEN (60) bytes of
* data by the call to skb_put_padto() above this is safe with
* respect to both the length of the first DMA descriptor (len)
* overflowing the available data and the length of the second DMA
* descriptor (skb->len - len) being negative.
*/
if (len == 0)
len = DPTR_ALIGN;
memcpy(buffer, skb->data, len);
dma_addr = dma_map_single(ndev->dev.parent, buffer, len, DMA_TO_DEVICE);
if (dma_mapping_error(ndev->dev.parent, dma_addr))

View File

@@ -659,6 +659,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
* policy filters on the host). Deliver these via the VF
* interface in the guest.
*/
rcu_read_lock();
vf_netdev = rcu_dereference(net_device_ctx->vf_netdev);
if (vf_netdev && (vf_netdev->flags & IFF_UP))
net = vf_netdev;
@@ -667,6 +668,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
skb = netvsc_alloc_recv_skb(net, packet, csum_info, *data, vlan_tci);
if (unlikely(!skb)) {
++net->stats.rx_dropped;
rcu_read_unlock();
return NVSP_STAT_FAIL;
}
@@ -696,6 +698,7 @@ int netvsc_recv_callback(struct hv_device *device_obj,
* TODO - use NAPI?
*/
netif_rx(skb);
rcu_read_unlock();
return 0;
}

View File

@@ -827,7 +827,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
return -EINVAL;
ret = virtio_net_hdr_from_skb(skb, &vnet_hdr,
macvtap_is_little_endian(q));
macvtap_is_little_endian(q), true);
if (ret)
BUG();

View File

@@ -21,6 +21,23 @@ MODULE_DESCRIPTION("Broadcom 63xx internal PHY driver");
MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
MODULE_LICENSE("GPL");
static int bcm63xx_config_intr(struct phy_device *phydev)
{
int reg, err;
reg = phy_read(phydev, MII_BCM63XX_IR);
if (reg < 0)
return reg;
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
reg &= ~MII_BCM63XX_IR_GMASK;
else
reg |= MII_BCM63XX_IR_GMASK;
err = phy_write(phydev, MII_BCM63XX_IR, reg);
return err;
}
static int bcm63xx_config_init(struct phy_device *phydev)
{
int reg, err;
@@ -55,7 +72,7 @@ static struct phy_driver bcm63xx_driver[] = {
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.ack_interrupt = bcm_phy_ack_intr,
.config_intr = bcm_phy_config_intr,
.config_intr = bcm63xx_config_intr,
}, {
/* same phy as above, with just a different OUI */
.phy_id = 0x002bdc00,
@@ -67,7 +84,7 @@ static struct phy_driver bcm63xx_driver[] = {
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.ack_interrupt = bcm_phy_ack_intr,
.config_intr = bcm_phy_config_intr,
.config_intr = bcm63xx_config_intr,
} };
module_phy_driver(bcm63xx_driver);

View File

@@ -1374,7 +1374,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
return -EINVAL;
ret = virtio_net_hdr_from_skb(skb, &gso,
tun_is_little_endian(tun));
tun_is_little_endian(tun), true);
if (ret) {
struct skb_shared_info *sinfo = skb_shinfo(skb);
pr_err("unexpected GSO type: "

View File

@@ -531,6 +531,7 @@ static const struct driver_info wwan_info = {
#define SAMSUNG_VENDOR_ID 0x04e8
#define LENOVO_VENDOR_ID 0x17ef
#define NVIDIA_VENDOR_ID 0x0955
#define HP_VENDOR_ID 0x03f0
static const struct usb_device_id products[] = {
/* BLACKLIST !!
@@ -677,6 +678,13 @@ static const struct usb_device_id products[] = {
.driver_info = 0,
},
/* HP lt2523 (Novatel E371) - handled by qmi_wwan */
{
USB_DEVICE_AND_INTERFACE_INFO(HP_VENDOR_ID, 0x421d, USB_CLASS_COMM,
USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
.driver_info = 0,
},
/* AnyDATA ADU960S - handled by qmi_wwan */
{
USB_DEVICE_AND_INTERFACE_INFO(0x16d5, 0x650a, USB_CLASS_COMM,

View File

@@ -654,6 +654,13 @@ static const struct usb_device_id products[] = {
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&qmi_wwan_info,
},
{ /* HP lt2523 (Novatel E371) */
USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x421d,
USB_CLASS_COMM,
USB_CDC_SUBCLASS_ETHERNET,
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&qmi_wwan_info,
},
{ /* HP lt4112 LTE/HSPA+ Gobi 4G Module (Huawei me906e) */
USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
.driver_info = (unsigned long)&qmi_wwan_info,

View File

@@ -32,7 +32,7 @@
#define NETNEXT_VERSION "08"
/* Information for net */
#define NET_VERSION "6"
#define NET_VERSION "7"
#define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION
#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
@@ -1730,7 +1730,7 @@ static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
u8 checksum = CHECKSUM_NONE;
u32 opts2, opts3;
if (tp->version == RTL_VER_01 || tp->version == RTL_VER_02)
if (!(tp->netdev->features & NETIF_F_RXCSUM))
goto return_result;
opts2 = le32_to_cpu(rx_desc->opts2);
@@ -3572,6 +3572,8 @@ static bool delay_autosuspend(struct r8152 *tp)
*/
if (!sw_linking && tp->rtl_ops.in_nway(tp))
return true;
else if (!skb_queue_empty(&tp->tx_queue))
return true;
else
return false;
}
@@ -4358,6 +4360,11 @@ static int rtl8152_probe(struct usb_interface *intf,
NETIF_F_HIGHDMA | NETIF_F_FRAGLIST |
NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
if (tp->version == RTL_VER_01) {
netdev->features &= ~NETIF_F_RXCSUM;
netdev->hw_features &= ~NETIF_F_RXCSUM;
}
netdev->ethtool_ops = &ops;
netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);

View File

@@ -840,7 +840,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
hdr = skb_vnet_hdr(skb);
if (virtio_net_hdr_from_skb(skb, &hdr->hdr,
virtio_is_little_endian(vi->vdev)))
virtio_is_little_endian(vi->vdev), false))
BUG();
if (vi->mergeable_rx_bufs)

View File

@@ -2887,7 +2887,7 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
memcpy(&vxlan->cfg, conf, sizeof(*conf));
if (!vxlan->cfg.dst_port) {
if (conf->flags & VXLAN_F_GPE)
vxlan->cfg.dst_port = 4790; /* IANA assigned VXLAN-GPE port */
vxlan->cfg.dst_port = htons(4790); /* IANA VXLAN-GPE port */
else
vxlan->cfg.dst_port = default_port;
}

View File

@@ -1092,6 +1092,7 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
enum pin_config_param param = pinconf_to_config_param(*config);
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
unsigned long flags;
u32 conf, pull, val, debounce;
u16 arg = 0;
@@ -1128,7 +1129,7 @@ static int byt_pin_config_get(struct pinctrl_dev *pctl_dev, unsigned int offset,
return -EINVAL;
raw_spin_lock_irqsave(&vg->lock, flags);
debounce = readl(byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG));
debounce = readl(db_reg);
raw_spin_unlock_irqrestore(&vg->lock, flags);
switch (debounce & BYT_DEBOUNCE_PULSE_MASK) {
@@ -1176,6 +1177,7 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
unsigned int param, arg;
void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG);
unsigned long flags;
u32 conf, val, debounce;
int i, ret = 0;
@@ -1238,36 +1240,40 @@ static int byt_pin_config_set(struct pinctrl_dev *pctl_dev,
break;
case PIN_CONFIG_INPUT_DEBOUNCE:
debounce = readl(byt_gpio_reg(vg, offset,
BYT_DEBOUNCE_REG));
conf &= ~BYT_DEBOUNCE_PULSE_MASK;
debounce = readl(db_reg);
debounce &= ~BYT_DEBOUNCE_PULSE_MASK;
switch (arg) {
case 0:
conf &= BYT_DEBOUNCE_EN;
break;
case 375:
conf |= BYT_DEBOUNCE_PULSE_375US;
debounce |= BYT_DEBOUNCE_PULSE_375US;
break;
case 750:
conf |= BYT_DEBOUNCE_PULSE_750US;
debounce |= BYT_DEBOUNCE_PULSE_750US;
break;
case 1500:
conf |= BYT_DEBOUNCE_PULSE_1500US;
debounce |= BYT_DEBOUNCE_PULSE_1500US;
break;
case 3000:
conf |= BYT_DEBOUNCE_PULSE_3MS;
debounce |= BYT_DEBOUNCE_PULSE_3MS;
break;
case 6000:
conf |= BYT_DEBOUNCE_PULSE_6MS;
debounce |= BYT_DEBOUNCE_PULSE_6MS;
break;
case 12000:
conf |= BYT_DEBOUNCE_PULSE_12MS;
debounce |= BYT_DEBOUNCE_PULSE_12MS;
break;
case 24000:
conf |= BYT_DEBOUNCE_PULSE_24MS;
debounce |= BYT_DEBOUNCE_PULSE_24MS;
break;
default:
ret = -EINVAL;
}
if (!ret)
writel(debounce, db_reg);
break;
default:
ret = -ENOTSUPP;

View File

@@ -19,7 +19,7 @@
#define BXT_PAD_OWN 0x020
#define BXT_HOSTSW_OWN 0x080
#define BXT_PADCFGLOCK 0x090
#define BXT_PADCFGLOCK 0x060
#define BXT_GPI_IE 0x110
#define BXT_COMMUNITY(s, e) \

View File

@@ -561,7 +561,7 @@ static const int ether_rgmii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
static const unsigned ether_rmii_pins[] = {30, 31, 32, 33, 34, 35, 36, 37, 39,
41, 42, 45};
static const int ether_rmii_muxvals[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
static const int ether_rmii_muxvals[] = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1};
static const unsigned i2c0_pins[] = {63, 64};
static const int i2c0_muxvals[] = {0, 0};
static const unsigned i2c1_pins[] = {65, 66};

View File

@@ -77,7 +77,7 @@ static int mfld_pb_probe(struct platform_device *pdev)
input_set_capability(input, EV_KEY, KEY_POWER);
error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0,
error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_ONESHOT,
DRIVER_NAME, input);
if (error) {
dev_err(&pdev->dev, "Unable to request irq %d for mfld power"

View File

@@ -163,17 +163,18 @@ void fb_dealloc_cmap(struct fb_cmap *cmap)
int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to)
{
int tooff = 0, fromoff = 0;
int size;
unsigned int tooff = 0, fromoff = 0;
size_t size;
if (to->start > from->start)
fromoff = to->start - from->start;
else
tooff = from->start - to->start;
size = to->len - tooff;
if (size > (int) (from->len - fromoff))
size = from->len - fromoff;
if (size <= 0)
if (fromoff >= from->len || tooff >= to->len)
return -EINVAL;
size = min_t(size_t, to->len - tooff, from->len - fromoff);
if (size == 0)
return -EINVAL;
size *= sizeof(u16);
@@ -187,17 +188,18 @@ int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to)
int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to)
{
int tooff = 0, fromoff = 0;
int size;
unsigned int tooff = 0, fromoff = 0;
size_t size;
if (to->start > from->start)
fromoff = to->start - from->start;
else
tooff = from->start - to->start;
size = to->len - tooff;
if (size > (int) (from->len - fromoff))
size = from->len - fromoff;
if (size <= 0)
if (fromoff >= from->len || tooff >= to->len)
return -EINVAL;
size = min_t(size_t, to->len - tooff, from->len - fromoff);
if (size == 0)
return -EINVAL;
size *= sizeof(u16);

View File

@@ -59,6 +59,7 @@
#define pr_fmt(fmt) "virtio-mmio: " fmt
#include <linux/acpi.h>
#include <linux/dma-mapping.h>
#include <linux/highmem.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -497,6 +498,7 @@ static int virtio_mmio_probe(struct platform_device *pdev)
struct virtio_mmio_device *vm_dev;
struct resource *mem;
unsigned long magic;
int rc;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem)
@@ -545,9 +547,25 @@ static int virtio_mmio_probe(struct platform_device *pdev)
}
vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID);
if (vm_dev->version == 1)
if (vm_dev->version == 1) {
writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE);
rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
/*
* In the legacy case, ensure our coherently-allocated virtio
* ring will be at an address expressable as a 32-bit PFN.
*/
if (!rc)
dma_set_coherent_mask(&pdev->dev,
DMA_BIT_MASK(32 + PAGE_SHIFT));
} else {
rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
}
if (rc)
rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (rc)
dev_warn(&pdev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n");
platform_set_drvdata(pdev, vm_dev);
return register_virtio_device(&vm_dev->vdev);

View File

@@ -159,6 +159,13 @@ static bool vring_use_dma_api(struct virtio_device *vdev)
if (xen_domain())
return true;
/*
* On ARM-based machines, the DMA ops will do the right thing,
* so always use them with legacy devices.
*/
if (IS_ENABLED(CONFIG_ARM) || IS_ENABLED(CONFIG_ARM64))
return !virtio_has_feature(vdev, VIRTIO_F_VERSION_1);
return false;
}

View File

@@ -3819,10 +3819,7 @@ cache_acl:
break;
case S_IFDIR:
inode->i_fop = &btrfs_dir_file_operations;
if (root == root->fs_info->tree_root)
inode->i_op = &btrfs_dir_ro_inode_operations;
else
inode->i_op = &btrfs_dir_inode_operations;
inode->i_op = &btrfs_dir_inode_operations;
break;
case S_IFLNK:
inode->i_op = &btrfs_symlink_inode_operations;
@@ -5682,6 +5679,7 @@ static struct inode *new_simple_dir(struct super_block *s,
inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID;
inode->i_op = &btrfs_dir_ro_inode_operations;
inode->i_opflags &= ~IOP_XATTR;
inode->i_fop = &simple_dir_operations;
inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
inode->i_mtime = current_time(inode);
@@ -10587,8 +10585,6 @@ static const struct inode_operations btrfs_dir_inode_operations = {
static const struct inode_operations btrfs_dir_ro_inode_operations = {
.lookup = btrfs_lookup,
.permission = btrfs_permission,
.get_acl = btrfs_get_acl,
.set_acl = btrfs_set_acl,
.update_time = btrfs_update_time,
};

View File

@@ -2678,7 +2678,8 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
sattr->ia_valid |= ATTR_MTIME;
/* Except MODE, it seems harmless of setting twice. */
if ((attrset[1] & FATTR4_WORD1_MODE))
if (opendata->o_arg.createmode != NFS4_CREATE_EXCLUSIVE &&
attrset[1] & FATTR4_WORD1_MODE)
sattr->ia_valid &= ~ATTR_MODE;
if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
@@ -8371,6 +8372,7 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,
goto out;
}
nfs4_sequence_free_slot(&lgp->res.seq_res);
err = nfs4_handle_exception(server, nfs4err, exception);
if (!status) {
if (exception->retry)

View File

@@ -95,10 +95,7 @@ unsigned int
xfs_alloc_set_aside(
struct xfs_mount *mp)
{
unsigned int blocks;
blocks = 4 + (mp->m_sb.sb_agcount * XFS_ALLOC_AGFL_RESERVE);
return blocks;
return mp->m_sb.sb_agcount * (XFS_ALLOC_AGFL_RESERVE + 4);
}
/*
@@ -365,35 +362,11 @@ xfs_alloc_fix_len(
return;
ASSERT(rlen >= args->minlen && rlen <= args->maxlen);
ASSERT(rlen % args->prod == args->mod);
ASSERT(args->pag->pagf_freeblks + args->pag->pagf_flcount >=
rlen + args->minleft);
args->len = rlen;
}
/*
* Fix up length if there is too little space left in the a.g.
* Return 1 if ok, 0 if too little, should give up.
*/
STATIC int
xfs_alloc_fix_minleft(
xfs_alloc_arg_t *args) /* allocation argument structure */
{
xfs_agf_t *agf; /* a.g. freelist header */
int diff; /* free space difference */
if (args->minleft == 0)
return 1;
agf = XFS_BUF_TO_AGF(args->agbp);
diff = be32_to_cpu(agf->agf_freeblks)
- args->len - args->minleft;
if (diff >= 0)
return 1;
args->len += diff; /* shrink the allocated space */
/* casts to (int) catch length underflows */
if ((int)args->len >= (int)args->minlen)
return 1;
args->agbno = NULLAGBLOCK;
return 0;
}
/*
* Update the two btrees, logically removing from freespace the extent
* starting at rbno, rlen blocks. The extent is contained within the
@@ -689,8 +662,6 @@ xfs_alloc_ag_vextent(
xfs_alloc_arg_t *args) /* argument structure for allocation */
{
int error=0;
xfs_extlen_t reservation;
xfs_extlen_t oldmax;
ASSERT(args->minlen > 0);
ASSERT(args->maxlen > 0);
@@ -698,20 +669,6 @@ xfs_alloc_ag_vextent(
ASSERT(args->mod < args->prod);
ASSERT(args->alignment > 0);
/*
* Clamp maxlen to the amount of free space minus any reservations
* that have been made.
*/
oldmax = args->maxlen;
reservation = xfs_ag_resv_needed(args->pag, args->resv);
if (args->maxlen > args->pag->pagf_freeblks - reservation)
args->maxlen = args->pag->pagf_freeblks - reservation;
if (args->maxlen == 0) {
args->agbno = NULLAGBLOCK;
args->maxlen = oldmax;
return 0;
}
/*
* Branch to correct routine based on the type.
*/
@@ -731,8 +688,6 @@ xfs_alloc_ag_vextent(
/* NOTREACHED */
}
args->maxlen = oldmax;
if (error || args->agbno == NULLAGBLOCK)
return error;
@@ -841,9 +796,6 @@ xfs_alloc_ag_vextent_exact(
args->len = XFS_AGBLOCK_MIN(tend, args->agbno + args->maxlen)
- args->agbno;
xfs_alloc_fix_len(args);
if (!xfs_alloc_fix_minleft(args))
goto not_found;
ASSERT(args->agbno + args->len <= tend);
/*
@@ -1149,12 +1101,7 @@ restart:
XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0);
ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length));
args->len = blen;
if (!xfs_alloc_fix_minleft(args)) {
xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
trace_xfs_alloc_near_nominleft(args);
return 0;
}
blen = args->len;
/*
* We are allocating starting at bnew for blen blocks.
*/
@@ -1346,12 +1293,6 @@ restart:
*/
args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen);
xfs_alloc_fix_len(args);
if (!xfs_alloc_fix_minleft(args)) {
trace_xfs_alloc_near_nominleft(args);
xfs_btree_del_cursor(bno_cur_lt, XFS_BTREE_NOERROR);
xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
return 0;
}
rlen = args->len;
(void)xfs_alloc_compute_diff(args->agbno, rlen, args->alignment,
args->datatype, ltbnoa, ltlena, &ltnew);
@@ -1553,8 +1494,6 @@ restart:
}
xfs_alloc_fix_len(args);
if (!xfs_alloc_fix_minleft(args))
goto out_nominleft;
rlen = args->len;
XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0);
/*
@@ -2056,7 +1995,7 @@ xfs_alloc_space_available(
int flags)
{
struct xfs_perag *pag = args->pag;
xfs_extlen_t longest;
xfs_extlen_t alloc_len, longest;
xfs_extlen_t reservation; /* blocks that are still reserved */
int available;
@@ -2066,17 +2005,28 @@ xfs_alloc_space_available(
reservation = xfs_ag_resv_needed(pag, args->resv);
/* do we have enough contiguous free space for the allocation? */
alloc_len = args->minlen + (args->alignment - 1) + args->minalignslop;
longest = xfs_alloc_longest_free_extent(args->mp, pag, min_free,
reservation);
if ((args->minlen + args->alignment + args->minalignslop - 1) > longest)
if (longest < alloc_len)
return false;
/* do we have enough free space remaining for the allocation? */
available = (int)(pag->pagf_freeblks + pag->pagf_flcount -
reservation - min_free - args->total);
if (available < (int)args->minleft || available <= 0)
reservation - min_free - args->minleft);
if (available < (int)max(args->total, alloc_len))
return false;
/*
* Clamp maxlen to the amount of free space available for the actual
* extent allocation.
*/
if (available < (int)args->maxlen && !(flags & XFS_ALLOC_FLAG_CHECK)) {
args->maxlen = available;
ASSERT(args->maxlen > 0);
ASSERT(args->maxlen >= args->minlen);
}
return true;
}
@@ -2122,7 +2072,8 @@ xfs_alloc_fix_freelist(
}
need = xfs_alloc_min_freelist(mp, pag);
if (!xfs_alloc_space_available(args, need, flags))
if (!xfs_alloc_space_available(args, need, flags |
XFS_ALLOC_FLAG_CHECK))
goto out_agbp_relse;
/*
@@ -2638,12 +2589,10 @@ xfs_alloc_vextent(
xfs_agblock_t agsize; /* allocation group size */
int error;
int flags; /* XFS_ALLOC_FLAG_... locking flags */
xfs_extlen_t minleft;/* minimum left value, temp copy */
xfs_mount_t *mp; /* mount structure pointer */
xfs_agnumber_t sagno; /* starting allocation group number */
xfs_alloctype_t type; /* input allocation type */
int bump_rotor = 0;
int no_min = 0;
xfs_agnumber_t rotorstep = xfs_rotorstep; /* inode32 agf stepper */
mp = args->mp;
@@ -2672,7 +2621,6 @@ xfs_alloc_vextent(
trace_xfs_alloc_vextent_badargs(args);
return 0;
}
minleft = args->minleft;
switch (type) {
case XFS_ALLOCTYPE_THIS_AG:
@@ -2683,9 +2631,7 @@ xfs_alloc_vextent(
*/
args->agno = XFS_FSB_TO_AGNO(mp, args->fsbno);
args->pag = xfs_perag_get(mp, args->agno);
args->minleft = 0;
error = xfs_alloc_fix_freelist(args, 0);
args->minleft = minleft;
if (error) {
trace_xfs_alloc_vextent_nofix(args);
goto error0;
@@ -2750,9 +2696,7 @@ xfs_alloc_vextent(
*/
for (;;) {
args->pag = xfs_perag_get(mp, args->agno);
if (no_min) args->minleft = 0;
error = xfs_alloc_fix_freelist(args, flags);
args->minleft = minleft;
if (error) {
trace_xfs_alloc_vextent_nofix(args);
goto error0;
@@ -2792,20 +2736,17 @@ xfs_alloc_vextent(
* or switch to non-trylock mode.
*/
if (args->agno == sagno) {
if (no_min == 1) {
if (flags == 0) {
args->agbno = NULLAGBLOCK;
trace_xfs_alloc_vextent_allfailed(args);
break;
}
if (flags == 0) {
no_min = 1;
} else {
flags = 0;
if (type == XFS_ALLOCTYPE_START_BNO) {
args->agbno = XFS_FSB_TO_AGBNO(mp,
args->fsbno);
args->type = XFS_ALLOCTYPE_NEAR_BNO;
}
flags = 0;
if (type == XFS_ALLOCTYPE_START_BNO) {
args->agbno = XFS_FSB_TO_AGBNO(mp,
args->fsbno);
args->type = XFS_ALLOCTYPE_NEAR_BNO;
}
}
xfs_perag_put(args->pag);

View File

@@ -56,7 +56,7 @@ typedef unsigned int xfs_alloctype_t;
#define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/
#define XFS_ALLOC_FLAG_NORMAP 0x00000004 /* don't modify the rmapbt */
#define XFS_ALLOC_FLAG_NOSHRINK 0x00000008 /* don't shrink the freelist */
#define XFS_ALLOC_FLAG_CHECK 0x00000010 /* test only, don't modify args */
/*
* Argument structure for xfs_alloc routines.

View File

@@ -131,9 +131,6 @@ xfs_attr_get(
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
return -EIO;
if (!xfs_inode_hasattr(ip))
return -ENOATTR;
error = xfs_attr_args_init(&args, ip, name, flags);
if (error)
return error;
@@ -392,9 +389,6 @@ xfs_attr_remove(
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
return -EIO;
if (!xfs_inode_hasattr(dp))
return -ENOATTR;
error = xfs_attr_args_init(&args, dp, name, flags);
if (error)
return error;

View File

@@ -3720,7 +3720,7 @@ xfs_bmap_btalloc(
align = xfs_get_cowextsz_hint(ap->ip);
else if (xfs_alloc_is_userdata(ap->datatype))
align = xfs_get_extsz_hint(ap->ip);
if (unlikely(align)) {
if (align) {
error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
align, 0, ap->eof, 0, ap->conv,
&ap->offset, &ap->length);
@@ -3792,7 +3792,7 @@ xfs_bmap_btalloc(
args.minlen = ap->minlen;
}
/* apply extent size hints if obtained earlier */
if (unlikely(align)) {
if (align) {
args.prod = align;
if ((args.mod = (xfs_extlen_t)do_mod(ap->offset, args.prod)))
args.mod = (xfs_extlen_t)(args.prod - args.mod);
@@ -3903,7 +3903,6 @@ xfs_bmap_btalloc(
args.fsbno = 0;
args.type = XFS_ALLOCTYPE_FIRST_AG;
args.total = ap->minlen;
args.minleft = 0;
if ((error = xfs_alloc_vextent(&args)))
return error;
ap->dfops->dop_low = true;
@@ -4437,8 +4436,6 @@ xfs_bmapi_allocate(
if (error)
return error;
if (bma->dfops->dop_low)
bma->minleft = 0;
if (bma->cur)
bma->cur->bc_private.b.firstblock = *bma->firstblock;
if (bma->blkno == NULLFSBLOCK)
@@ -4610,8 +4607,6 @@ xfs_bmapi_write(
int n; /* current extent index */
xfs_fileoff_t obno; /* old block number (offset) */
int whichfork; /* data or attr fork */
char inhole; /* current location is hole in file */
char wasdelay; /* old extent was delayed */
#ifdef DEBUG
xfs_fileoff_t orig_bno; /* original block number value */
@@ -4697,22 +4692,44 @@ xfs_bmapi_write(
bma.firstblock = firstblock;
while (bno < end && n < *nmap) {
inhole = eof || bma.got.br_startoff > bno;
wasdelay = !inhole && isnullstartblock(bma.got.br_startblock);
bool need_alloc = false, wasdelay = false;
/*
* Make sure we only reflink into a hole.
*/
if (flags & XFS_BMAPI_REMAP)
ASSERT(inhole);
if (flags & XFS_BMAPI_COWFORK)
ASSERT(!inhole);
/* in hole or beyoned EOF? */
if (eof || bma.got.br_startoff > bno) {
if (flags & XFS_BMAPI_DELALLOC) {
/*
* For the COW fork we can reasonably get a
* request for converting an extent that races
* with other threads already having converted
* part of it, as there converting COW to
* regular blocks is not protected using the
* IOLOCK.
*/
ASSERT(flags & XFS_BMAPI_COWFORK);
if (!(flags & XFS_BMAPI_COWFORK)) {
error = -EIO;
goto error0;
}
if (eof || bno >= end)
break;
} else {
need_alloc = true;
}
} else {
/*
* Make sure we only reflink into a hole.
*/
ASSERT(!(flags & XFS_BMAPI_REMAP));
if (isnullstartblock(bma.got.br_startblock))
wasdelay = true;
}
/*
* First, deal with the hole before the allocated space
* that we found, if any.
*/
if (inhole || wasdelay) {
if (need_alloc || wasdelay) {
bma.eof = eof;
bma.conv = !!(flags & XFS_BMAPI_CONVERT);
bma.wasdel = wasdelay;

View File

@@ -110,6 +110,9 @@ struct xfs_extent_free_item
/* Map something in the CoW fork. */
#define XFS_BMAPI_COWFORK 0x200
/* Only convert delalloc space, don't allocate entirely new extents */
#define XFS_BMAPI_DELALLOC 0x400
#define XFS_BMAPI_FLAGS \
{ XFS_BMAPI_ENTIRE, "ENTIRE" }, \
{ XFS_BMAPI_METADATA, "METADATA" }, \
@@ -120,7 +123,8 @@ struct xfs_extent_free_item
{ XFS_BMAPI_CONVERT, "CONVERT" }, \
{ XFS_BMAPI_ZERO, "ZERO" }, \
{ XFS_BMAPI_REMAP, "REMAP" }, \
{ XFS_BMAPI_COWFORK, "COWFORK" }
{ XFS_BMAPI_COWFORK, "COWFORK" }, \
{ XFS_BMAPI_DELALLOC, "DELALLOC" }
static inline int xfs_bmapi_aflag(int w)

View File

@@ -502,12 +502,11 @@ try_another_ag:
if (args.fsbno == NULLFSBLOCK && args.minleft) {
/*
* Could not find an AG with enough free space to satisfy
* a full btree split. Try again without minleft and if
* a full btree split. Try again and if
* successful activate the lowspace algorithm.
*/
args.fsbno = 0;
args.type = XFS_ALLOCTYPE_FIRST_AG;
args.minleft = 0;
error = xfs_alloc_vextent(&args);
if (error)
goto error0;

View File

@@ -36,21 +36,29 @@
struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR };
/*
* @mode, if set, indicates that the type field needs to be set up.
* This uses the transformation from file mode to DT_* as defined in linux/fs.h
* for file type specification. This will be propagated into the directory
* structure if appropriate for the given operation and filesystem config.
* Convert inode mode to directory entry filetype
*/
const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
[0] = XFS_DIR3_FT_UNKNOWN,
[S_IFREG >> S_SHIFT] = XFS_DIR3_FT_REG_FILE,
[S_IFDIR >> S_SHIFT] = XFS_DIR3_FT_DIR,
[S_IFCHR >> S_SHIFT] = XFS_DIR3_FT_CHRDEV,
[S_IFBLK >> S_SHIFT] = XFS_DIR3_FT_BLKDEV,
[S_IFIFO >> S_SHIFT] = XFS_DIR3_FT_FIFO,
[S_IFSOCK >> S_SHIFT] = XFS_DIR3_FT_SOCK,
[S_IFLNK >> S_SHIFT] = XFS_DIR3_FT_SYMLINK,
};
unsigned char xfs_mode_to_ftype(int mode)
{
switch (mode & S_IFMT) {
case S_IFREG:
return XFS_DIR3_FT_REG_FILE;
case S_IFDIR:
return XFS_DIR3_FT_DIR;
case S_IFCHR:
return XFS_DIR3_FT_CHRDEV;
case S_IFBLK:
return XFS_DIR3_FT_BLKDEV;
case S_IFIFO:
return XFS_DIR3_FT_FIFO;
case S_IFSOCK:
return XFS_DIR3_FT_SOCK;
case S_IFLNK:
return XFS_DIR3_FT_SYMLINK;
default:
return XFS_DIR3_FT_UNKNOWN;
}
}
/*
* ASCII case-insensitive (ie. A-Z) support for directories that was
@@ -631,7 +639,8 @@ xfs_dir2_isblock(
if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
return rval;
rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize;
ASSERT(rval == 0 || args->dp->i_d.di_size == args->geo->blksize);
if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize)
return -EFSCORRUPTED;
*vp = rval;
return 0;
}

View File

@@ -18,6 +18,9 @@
#ifndef __XFS_DIR2_H__
#define __XFS_DIR2_H__
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
struct xfs_defer_ops;
struct xfs_da_args;
struct xfs_inode;
@@ -32,10 +35,9 @@ struct xfs_dir2_data_unused;
extern struct xfs_name xfs_name_dotdot;
/*
* directory filetype conversion tables.
* Convert inode mode to directory entry filetype
*/
#define S_SHIFT 12
extern const unsigned char xfs_mode_to_ftype[];
extern unsigned char xfs_mode_to_ftype(int mode);
/*
* directory operations vector for encode/decode routines

View File

@@ -29,6 +29,7 @@
#include "xfs_icache.h"
#include "xfs_trans.h"
#include "xfs_ialloc.h"
#include "xfs_dir2.h"
/*
* Check that none of the inode's in the buffer have a next
@@ -386,6 +387,7 @@ xfs_dinode_verify(
struct xfs_inode *ip,
struct xfs_dinode *dip)
{
uint16_t mode;
uint16_t flags;
uint64_t flags2;
@@ -396,8 +398,12 @@ xfs_dinode_verify(
if (be64_to_cpu(dip->di_size) & (1ULL << 63))
return false;
/* No zero-length symlinks. */
if (S_ISLNK(be16_to_cpu(dip->di_mode)) && dip->di_size == 0)
mode = be16_to_cpu(dip->di_mode);
if (mode && xfs_mode_to_ftype(mode) == XFS_DIR3_FT_UNKNOWN)
return false;
/* No zero-length symlinks/dirs. */
if ((S_ISLNK(mode) || S_ISDIR(mode)) && dip->di_size == 0)
return false;
/* only version 3 or greater inodes are extensively verified here */

View File

@@ -242,7 +242,7 @@ xfs_mount_validate_sb(
sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG ||
sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
sbp->sb_blocksize != (1 << sbp->sb_blocklog) ||
sbp->sb_dirblklog > XFS_MAX_BLOCKSIZE_LOG ||
sbp->sb_dirblklog + sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
sbp->sb_inodesize < XFS_DINODE_MIN_SIZE ||
sbp->sb_inodesize > XFS_DINODE_MAX_SIZE ||
sbp->sb_inodelog < XFS_DINODE_MIN_LOG ||

View File

@@ -528,7 +528,6 @@ xfs_getbmap(
xfs_bmbt_irec_t *map; /* buffer for user's data */
xfs_mount_t *mp; /* file system mount point */
int nex; /* # of user extents can do */
int nexleft; /* # of user extents left */
int subnex; /* # of bmapi's can do */
int nmap; /* number of map entries */
struct getbmapx *out; /* output structure */
@@ -686,10 +685,8 @@ xfs_getbmap(
goto out_free_map;
}
nexleft = nex;
do {
nmap = (nexleft > subnex) ? subnex : nexleft;
nmap = (nex> subnex) ? subnex : nex;
error = xfs_bmapi_read(ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
XFS_BB_TO_FSB(mp, bmv->bmv_length),
map, &nmap, bmapi_flags);
@@ -697,8 +694,8 @@ xfs_getbmap(
goto out_free_map;
ASSERT(nmap <= subnex);
for (i = 0; i < nmap && nexleft && bmv->bmv_length &&
cur_ext < bmv->bmv_count; i++) {
for (i = 0; i < nmap && bmv->bmv_length &&
cur_ext < bmv->bmv_count - 1; i++) {
out[cur_ext].bmv_oflags = 0;
if (map[i].br_state == XFS_EXT_UNWRITTEN)
out[cur_ext].bmv_oflags |= BMV_OF_PREALLOC;
@@ -760,16 +757,27 @@ xfs_getbmap(
continue;
}
/*
* In order to report shared extents accurately,
* we report each distinct shared/unshared part
* of a single bmbt record using multiple bmap
* extents. To make that happen, we iterate the
* same map array item multiple times, each
* time trimming out the subextent that we just
* reported.
*
* Because of this, we must check the out array
* index (cur_ext) directly against bmv_count-1
* to avoid overflows.
*/
if (inject_map.br_startblock != NULLFSBLOCK) {
map[i] = inject_map;
i--;
} else
nexleft--;
}
bmv->bmv_entries++;
cur_ext++;
}
} while (nmap && nexleft && bmv->bmv_length &&
cur_ext < bmv->bmv_count);
} while (nmap && bmv->bmv_length && cur_ext < bmv->bmv_count - 1);
out_free_map:
kmem_free(map);

View File

@@ -423,6 +423,7 @@ retry:
out_free_pages:
for (i = 0; i < bp->b_page_count; i++)
__free_page(bp->b_pages[i]);
bp->b_flags &= ~_XBF_PAGES;
return error;
}

View File

@@ -710,6 +710,10 @@ xfs_dq_get_next_id(
/* Simple advance */
next_id = *id + 1;
/* If we'd wrap past the max ID, stop */
if (next_id < *id)
return -ENOENT;
/* If new ID is within the current chunk, advancing it sufficed */
if (next_id % mp->m_quotainfo->qi_dqperchunk) {
*id = next_id;

View File

@@ -681,7 +681,7 @@ xfs_iomap_write_allocate(
xfs_trans_t *tp;
int nimaps;
int error = 0;
int flags = 0;
int flags = XFS_BMAPI_DELALLOC;
int nres;
if (whichfork == XFS_COW_FORK)

View File

@@ -97,13 +97,28 @@ xfs_init_security(
static void
xfs_dentry_to_name(
struct xfs_name *namep,
struct dentry *dentry)
{
namep->name = dentry->d_name.name;
namep->len = dentry->d_name.len;
namep->type = XFS_DIR3_FT_UNKNOWN;
}
static int
xfs_dentry_mode_to_name(
struct xfs_name *namep,
struct dentry *dentry,
int mode)
{
namep->name = dentry->d_name.name;
namep->len = dentry->d_name.len;
namep->type = xfs_mode_to_ftype[(mode & S_IFMT) >> S_SHIFT];
namep->type = xfs_mode_to_ftype(mode);
if (unlikely(namep->type == XFS_DIR3_FT_UNKNOWN))
return -EFSCORRUPTED;
return 0;
}
STATIC void
@@ -119,7 +134,7 @@ xfs_cleanup_inode(
* xfs_init_security we must back out.
* ENOSPC can hit here, among other things.
*/
xfs_dentry_to_name(&teardown, dentry, 0);
xfs_dentry_to_name(&teardown, dentry);
xfs_remove(XFS_I(dir), &teardown, XFS_I(inode));
}
@@ -154,8 +169,12 @@ xfs_generic_create(
if (error)
return error;
/* Verify mode is valid also for tmpfile case */
error = xfs_dentry_mode_to_name(&name, dentry, mode);
if (unlikely(error))
goto out_free_acl;
if (!tmpfile) {
xfs_dentry_to_name(&name, dentry, mode);
error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
} else {
error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip);
@@ -248,7 +267,7 @@ xfs_vn_lookup(
if (dentry->d_name.len >= MAXNAMELEN)
return ERR_PTR(-ENAMETOOLONG);
xfs_dentry_to_name(&name, dentry, 0);
xfs_dentry_to_name(&name, dentry);
error = xfs_lookup(XFS_I(dir), &name, &cip, NULL);
if (unlikely(error)) {
if (unlikely(error != -ENOENT))
@@ -275,7 +294,7 @@ xfs_vn_ci_lookup(
if (dentry->d_name.len >= MAXNAMELEN)
return ERR_PTR(-ENAMETOOLONG);
xfs_dentry_to_name(&xname, dentry, 0);
xfs_dentry_to_name(&xname, dentry);
error = xfs_lookup(XFS_I(dir), &xname, &ip, &ci_name);
if (unlikely(error)) {
if (unlikely(error != -ENOENT))
@@ -310,7 +329,9 @@ xfs_vn_link(
struct xfs_name name;
int error;
xfs_dentry_to_name(&name, dentry, inode->i_mode);
error = xfs_dentry_mode_to_name(&name, dentry, inode->i_mode);
if (unlikely(error))
return error;
error = xfs_link(XFS_I(dir), XFS_I(inode), &name);
if (unlikely(error))
@@ -329,7 +350,7 @@ xfs_vn_unlink(
struct xfs_name name;
int error;
xfs_dentry_to_name(&name, dentry, 0);
xfs_dentry_to_name(&name, dentry);
error = xfs_remove(XFS_I(dir), &name, XFS_I(d_inode(dentry)));
if (error)
@@ -359,7 +380,9 @@ xfs_vn_symlink(
mode = S_IFLNK |
(irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO);
xfs_dentry_to_name(&name, dentry, mode);
error = xfs_dentry_mode_to_name(&name, dentry, mode);
if (unlikely(error))
goto out;
error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip);
if (unlikely(error))
@@ -395,6 +418,7 @@ xfs_vn_rename(
{
struct inode *new_inode = d_inode(ndentry);
int omode = 0;
int error;
struct xfs_name oname;
struct xfs_name nname;
@@ -405,8 +429,14 @@ xfs_vn_rename(
if (flags & RENAME_EXCHANGE)
omode = d_inode(ndentry)->i_mode;
xfs_dentry_to_name(&oname, odentry, omode);
xfs_dentry_to_name(&nname, ndentry, d_inode(odentry)->i_mode);
error = xfs_dentry_mode_to_name(&oname, odentry, omode);
if (omode && unlikely(error))
return error;
error = xfs_dentry_mode_to_name(&nname, ndentry,
d_inode(odentry)->i_mode);
if (unlikely(error))
return error;
return xfs_rename(XFS_I(odir), &oname, XFS_I(d_inode(odentry)),
XFS_I(ndir), &nname,

View File

@@ -330,11 +330,11 @@ static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y)
}
#define ASSERT_ALWAYS(expr) \
(unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
(likely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
#ifdef DEBUG
#define ASSERT(expr) \
(unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
(likely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
#ifndef STATIC
# define STATIC noinline
@@ -345,7 +345,7 @@ static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y)
#ifdef XFS_WARN
#define ASSERT(expr) \
(unlikely(expr) ? (void)0 : asswarn(#expr, __FILE__, __LINE__))
(likely(expr) ? (void)0 : asswarn(#expr, __FILE__, __LINE__))
#ifndef STATIC
# define STATIC static noinline

View File

@@ -3324,12 +3324,8 @@ xfs_log_force(
xfs_mount_t *mp,
uint flags)
{
int error;
trace_xfs_log_force(mp, 0, _RET_IP_);
error = _xfs_log_force(mp, flags, NULL);
if (error)
xfs_warn(mp, "%s: error %d returned.", __func__, error);
_xfs_log_force(mp, flags, NULL);
}
/*
@@ -3473,12 +3469,8 @@ xfs_log_force_lsn(
xfs_lsn_t lsn,
uint flags)
{
int error;
trace_xfs_log_force(mp, lsn, _RET_IP_);
error = _xfs_log_force_lsn(mp, lsn, flags, NULL);
if (error)
xfs_warn(mp, "%s: error %d returned.", __func__, error);
_xfs_log_force_lsn(mp, lsn, flags, NULL);
}
/*

View File

@@ -1177,7 +1177,8 @@ xfs_qm_dqusage_adjust(
* the case in all other instances. It's OK that we do this because
* quotacheck is done only at mount time.
*/
error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_EXCL, &ip);
error = xfs_iget(mp, NULL, ino, XFS_IGET_DONTCACHE, XFS_ILOCK_EXCL,
&ip);
if (error) {
*res = BULKSTAT_RV_NOTHING;
return error;

View File

@@ -284,7 +284,7 @@ extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
unsigned long map_offset);
extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
unsigned long pnum);
extern int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
enum zone_type target);
extern bool zone_can_shift(unsigned long pfn, unsigned long nr_pages,
enum zone_type target, int *zone_shift);
#endif /* __LINUX_MEMORY_HOTPLUG_H */

View File

@@ -972,12 +972,16 @@ static __always_inline struct zoneref *next_zones_zonelist(struct zoneref *z,
* @zonelist - The zonelist to search for a suitable zone
* @highest_zoneidx - The zone index of the highest zone to return
* @nodes - An optional nodemask to filter the zonelist with
* @zone - The first suitable zone found is returned via this parameter
* @return - Zoneref pointer for the first suitable zone found (see below)
*
* This function returns the first zone at or below a given zone index that is
* within the allowed nodemask. The zoneref returned is a cursor that can be
* used to iterate the zonelist with next_zones_zonelist by advancing it by
* one before calling.
*
* When no eligible zone is found, zoneref->zone is NULL (zoneref itself is
* never NULL). This may happen either genuinely, or due to concurrent nodemask
* update due to cpuset modification.
*/
static inline struct zoneref *first_zones_zonelist(struct zonelist *zonelist,
enum zone_type highest_zoneidx,

View File

@@ -282,7 +282,7 @@ enum nfsstat4 {
static inline bool seqid_mutating_err(u32 err)
{
/* rfc 3530 section 8.1.5: */
/* See RFC 7530, section 9.1.7 */
switch (err) {
case NFS4ERR_STALE_CLIENTID:
case NFS4ERR_STALE_STATEID:
@@ -291,6 +291,7 @@ static inline bool seqid_mutating_err(u32 err)
case NFS4ERR_BADXDR:
case NFS4ERR_RESOURCE:
case NFS4ERR_NOFILEHANDLE:
case NFS4ERR_MOVED:
return false;
};
return true;

View File

@@ -216,5 +216,6 @@ void rpc_clnt_xprt_switch_put(struct rpc_clnt *);
void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *, struct rpc_xprt *);
bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
const struct sockaddr *sap);
void rpc_cleanup_clids(void);
#endif /* __KERNEL__ */
#endif /* _LINUX_SUNRPC_CLNT_H */

View File

@@ -62,8 +62,13 @@ static inline unsigned int tcp_optlen(const struct sk_buff *skb)
/* TCP Fast Open Cookie as stored in memory */
struct tcp_fastopen_cookie {
union {
u8 val[TCP_FASTOPEN_COOKIE_MAX];
#if IS_ENABLED(CONFIG_IPV6)
struct in6_addr addr;
#endif
};
s8 len;
u8 val[TCP_FASTOPEN_COOKIE_MAX];
bool exp; /* In RFC6994 experimental option format */
};

View File

@@ -56,7 +56,8 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
struct virtio_net_hdr *hdr,
bool little_endian)
bool little_endian,
bool has_data_valid)
{
memset(hdr, 0, sizeof(*hdr));
@@ -91,7 +92,8 @@ static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
skb_checksum_start_offset(skb));
hdr->csum_offset = __cpu_to_virtio16(little_endian,
skb->csum_offset);
} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
} else if (has_data_valid &&
skb->ip_summed == CHECKSUM_UNNECESSARY) {
hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID;
} /* else everything is zero */

View File

@@ -43,13 +43,12 @@ struct lwtunnel_encap_ops {
int (*get_encap_size)(struct lwtunnel_state *lwtstate);
int (*cmp_encap)(struct lwtunnel_state *a, struct lwtunnel_state *b);
int (*xmit)(struct sk_buff *skb);
struct module *owner;
};
#ifdef CONFIG_LWTUNNEL
static inline void lwtstate_free(struct lwtunnel_state *lws)
{
kfree(lws);
}
void lwtstate_free(struct lwtunnel_state *lws);
static inline struct lwtunnel_state *
lwtstate_get(struct lwtunnel_state *lws)
@@ -106,6 +105,8 @@ int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
unsigned int num);
int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
unsigned int num);
int lwtunnel_valid_encap_type(u16 encap_type);
int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len);
int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
struct nlattr *encap,
unsigned int family, const void *cfg,
@@ -169,6 +170,15 @@ static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
return -EOPNOTSUPP;
}
static inline int lwtunnel_valid_encap_type(u16 encap_type)
{
return -EOPNOTSUPP;
}
static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len)
{
return -EOPNOTSUPP;
}
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
struct nlattr *encap,
unsigned int family, const void *cfg,

View File

@@ -30,7 +30,7 @@
* SOFTWARE.
*/
#ifndef CXGB3_ABI_USER_H
#define CXBG3_ABI_USER_H
#define CXGB3_ABI_USER_H
#include <linux/types.h>

View File

@@ -9508,6 +9508,37 @@ static int perf_event_set_clock(struct perf_event *event, clockid_t clk_id)
return 0;
}
/*
* Variation on perf_event_ctx_lock_nested(), except we take two context
* mutexes.
*/
static struct perf_event_context *
__perf_event_ctx_lock_double(struct perf_event *group_leader,
struct perf_event_context *ctx)
{
struct perf_event_context *gctx;
again:
rcu_read_lock();
gctx = READ_ONCE(group_leader->ctx);
if (!atomic_inc_not_zero(&gctx->refcount)) {
rcu_read_unlock();
goto again;
}
rcu_read_unlock();
mutex_lock_double(&gctx->mutex, &ctx->mutex);
if (group_leader->ctx != gctx) {
mutex_unlock(&ctx->mutex);
mutex_unlock(&gctx->mutex);
put_ctx(gctx);
goto again;
}
return gctx;
}
/**
* sys_perf_event_open - open a performance event, associate it to a task/cpu
*
@@ -9754,12 +9785,31 @@ SYSCALL_DEFINE5(perf_event_open,
}
if (move_group) {
gctx = group_leader->ctx;
mutex_lock_double(&gctx->mutex, &ctx->mutex);
gctx = __perf_event_ctx_lock_double(group_leader, ctx);
if (gctx->task == TASK_TOMBSTONE) {
err = -ESRCH;
goto err_locked;
}
/*
* Check if we raced against another sys_perf_event_open() call
* moving the software group underneath us.
*/
if (!(group_leader->group_caps & PERF_EV_CAP_SOFTWARE)) {
/*
* If someone moved the group out from under us, check
* if this new event wound up on the same ctx, if so
* its the regular !move_group case, otherwise fail.
*/
if (gctx != ctx) {
err = -EINVAL;
goto err_locked;
} else {
perf_event_ctx_unlock(group_leader, gctx);
move_group = 0;
}
}
} else {
mutex_lock(&ctx->mutex);
}
@@ -9861,7 +9911,7 @@ SYSCALL_DEFINE5(perf_event_open,
perf_unpin_context(ctx);
if (move_group)
mutex_unlock(&gctx->mutex);
perf_event_ctx_unlock(group_leader, gctx);
mutex_unlock(&ctx->mutex);
if (task) {
@@ -9887,7 +9937,7 @@ SYSCALL_DEFINE5(perf_event_open,
err_locked:
if (move_group)
mutex_unlock(&gctx->mutex);
perf_event_ctx_unlock(group_leader, gctx);
mutex_unlock(&ctx->mutex);
/* err_file: */
fput(event_file);

View File

@@ -2560,6 +2560,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int
break;
if (neg)
continue;
val = convmul * val / convdiv;
if ((min && val < *min) || (max && val > *max))
continue;
*i = val;

View File

@@ -128,10 +128,10 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
struct hlist_head *hashent = ucounts_hashentry(ns, uid);
struct ucounts *ucounts, *new;
spin_lock(&ucounts_lock);
spin_lock_irq(&ucounts_lock);
ucounts = find_ucounts(ns, uid, hashent);
if (!ucounts) {
spin_unlock(&ucounts_lock);
spin_unlock_irq(&ucounts_lock);
new = kzalloc(sizeof(*new), GFP_KERNEL);
if (!new)
@@ -141,7 +141,7 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
new->uid = uid;
atomic_set(&new->count, 0);
spin_lock(&ucounts_lock);
spin_lock_irq(&ucounts_lock);
ucounts = find_ucounts(ns, uid, hashent);
if (ucounts) {
kfree(new);
@@ -152,16 +152,18 @@ static struct ucounts *get_ucounts(struct user_namespace *ns, kuid_t uid)
}
if (!atomic_add_unless(&ucounts->count, 1, INT_MAX))
ucounts = NULL;
spin_unlock(&ucounts_lock);
spin_unlock_irq(&ucounts_lock);
return ucounts;
}
static void put_ucounts(struct ucounts *ucounts)
{
unsigned long flags;
if (atomic_dec_and_test(&ucounts->count)) {
spin_lock(&ucounts_lock);
spin_lock_irqsave(&ucounts_lock, flags);
hlist_del_init(&ucounts->node);
spin_unlock(&ucounts_lock);
spin_unlock_irqrestore(&ucounts_lock, flags);
kfree(ucounts);
}

View File

@@ -772,6 +772,12 @@ struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr,
assert_spin_locked(pmd_lockptr(mm, pmd));
/*
* When we COW a devmap PMD entry, we split it into PTEs, so we should
* not be in this function with `flags & FOLL_COW` set.
*/
WARN_ONCE(flags & FOLL_COW, "mm: In follow_devmap_pmd with FOLL_COW set");
if (flags & FOLL_WRITE && !pmd_write(*pmd))
return NULL;
@@ -1118,6 +1124,16 @@ out_unlock:
return ret;
}
/*
* FOLL_FORCE can write to even unwritable pmd's, but only
* after we've gone through a COW cycle and they are dirty.
*/
static inline bool can_follow_write_pmd(pmd_t pmd, unsigned int flags)
{
return pmd_write(pmd) ||
((flags & FOLL_FORCE) && (flags & FOLL_COW) && pmd_dirty(pmd));
}
struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
unsigned long addr,
pmd_t *pmd,
@@ -1128,7 +1144,7 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
assert_spin_locked(pmd_lockptr(mm, pmd));
if (flags & FOLL_WRITE && !pmd_write(*pmd))
if (flags & FOLL_WRITE && !can_follow_write_pmd(*pmd, flags))
goto out;
/* Avoid dumping huge zero page */

View File

@@ -4360,9 +4360,9 @@ static int mem_cgroup_do_precharge(unsigned long count)
return ret;
}
/* Try charges one by one with reclaim */
/* Try charges one by one with reclaim, but do not retry */
while (count--) {
ret = try_charge(mc.to, GFP_KERNEL & ~__GFP_NORETRY, 1);
ret = try_charge(mc.to, GFP_KERNEL | __GFP_NORETRY, 1);
if (ret)
return ret;
mc.precharge++;

View File

@@ -1033,36 +1033,39 @@ static void node_states_set_node(int node, struct memory_notify *arg)
node_set_state(node, N_MEMORY);
}
int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
enum zone_type target)
bool zone_can_shift(unsigned long pfn, unsigned long nr_pages,
enum zone_type target, int *zone_shift)
{
struct zone *zone = page_zone(pfn_to_page(pfn));
enum zone_type idx = zone_idx(zone);
int i;
*zone_shift = 0;
if (idx < target) {
/* pages must be at end of current zone */
if (pfn + nr_pages != zone_end_pfn(zone))
return 0;
return false;
/* no zones in use between current zone and target */
for (i = idx + 1; i < target; i++)
if (zone_is_initialized(zone - idx + i))
return 0;
return false;
}
if (target < idx) {
/* pages must be at beginning of current zone */
if (pfn != zone->zone_start_pfn)
return 0;
return false;
/* no zones in use between current zone and target */
for (i = target + 1; i < idx; i++)
if (zone_is_initialized(zone - idx + i))
return 0;
return false;
}
return target - idx;
*zone_shift = target - idx;
return true;
}
/* Must be protected by mem_hotplug_begin() */
@@ -1089,10 +1092,13 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
!can_online_high_movable(zone))
return -EINVAL;
if (online_type == MMOP_ONLINE_KERNEL)
zone_shift = zone_can_shift(pfn, nr_pages, ZONE_NORMAL);
else if (online_type == MMOP_ONLINE_MOVABLE)
zone_shift = zone_can_shift(pfn, nr_pages, ZONE_MOVABLE);
if (online_type == MMOP_ONLINE_KERNEL) {
if (!zone_can_shift(pfn, nr_pages, ZONE_NORMAL, &zone_shift))
return -EINVAL;
} else if (online_type == MMOP_ONLINE_MOVABLE) {
if (!zone_can_shift(pfn, nr_pages, ZONE_MOVABLE, &zone_shift))
return -EINVAL;
}
zone = move_pfn_range(zone_shift, pfn, pfn + nr_pages);
if (!zone)

View File

@@ -2024,8 +2024,8 @@ retry_cpuset:
nmask = policy_nodemask(gfp, pol);
zl = policy_zonelist(gfp, pol, node);
mpol_cond_put(pol);
page = __alloc_pages_nodemask(gfp, order, zl, nmask);
mpol_cond_put(pol);
out:
if (unlikely(!page && read_mems_allowed_retry(cpuset_mems_cookie)))
goto retry_cpuset;

Some files were not shown because too many files have changed in this diff Show More